@sima-land/ui-nucleons 44.2.10 → 45.0.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/_internal/custom-scrollbar/index.d.ts +13 -7
- package/_internal/custom-scrollbar/index.js +29 -15
- package/_internal/dropdown-loading/index.d.ts +3 -3
- package/_internal/dropdown-loading/index.js +4 -2
- package/_internal/page-scroll-lock/adapters/body-scroll-lock.d.ts +39 -0
- package/_internal/page-scroll-lock/adapters/body-scroll-lock.js +62 -0
- package/_internal/page-scroll-lock/adapters/ui-nucleons.d.ts +25 -0
- package/_internal/page-scroll-lock/adapters/ui-nucleons.js +103 -0
- package/_internal/page-scroll-lock/context.d.ts +13 -0
- package/_internal/page-scroll-lock/context.js +54 -0
- package/_internal/page-scroll-lock/hook.d.ts +12 -0
- package/_internal/page-scroll-lock/hook.js +26 -0
- package/_internal/page-scroll-lock/index.d.ts +4 -0
- package/_internal/page-scroll-lock/index.js +9 -0
- package/_internal/page-scroll-lock/types.d.ts +22 -0
- package/_internal/{checkbox/index.js → page-scroll-lock/types.js} +0 -0
- package/_internal/readme.md +2 -0
- package/_internal/utils/dropdown.d.ts +1 -0
- package/_internal/utils/dropdown.js +1 -0
- package/alert/alert.module.scss +1 -24
- package/alert/index.d.ts +11 -17
- package/alert/index.js +33 -16
- package/arrow-button/arrow-button.module.scss +2 -0
- package/arrow-button/index.d.ts +2 -2
- package/autocomplete/autocomplete.d.ts +8 -0
- package/autocomplete/autocomplete.js +190 -0
- package/autocomplete/autocomplete.module.scss +2 -15
- package/autocomplete/index.d.ts +2 -27
- package/autocomplete/index.js +2 -126
- package/autocomplete/types.d.ts +19 -0
- package/autocomplete/types.js +2 -0
- package/autocomplete-deprecated/autocomplete.module.scss +20 -0
- package/autocomplete-deprecated/index.d.ts +28 -0
- package/autocomplete-deprecated/index.js +130 -0
- package/avatar/index.d.ts +2 -2
- package/avatar/user.d.ts +1 -1
- package/base-input/base-input.d.ts +11 -0
- package/base-input/base-input.js +96 -0
- package/base-input/base-input.module.scss +3 -3
- package/base-input/index.d.ts +2 -23
- package/base-input/index.js +2 -76
- package/base-input/types.d.ts +31 -0
- package/base-input/types.js +2 -0
- package/base-input/utils.d.ts +6 -0
- package/base-input/utils.js +14 -0
- package/base-input-deprecated/base-input.module.scss +66 -0
- package/base-input-deprecated/index.d.ts +24 -0
- package/base-input-deprecated/index.js +80 -0
- package/bordered-layout/index.d.ts +1 -0
- package/bordered-layout/index.js +1 -0
- package/bottom-bar/bottom-bar-util.scss +20 -0
- package/bottom-bar/bottom-bar.d.ts +12 -0
- package/bottom-bar/bottom-bar.js +47 -0
- package/bottom-bar/bottom-bar.module.scss +14 -0
- package/bottom-bar/index.d.ts +2 -21
- package/bottom-bar/index.js +5 -44
- package/bottom-bar/types.d.ts +10 -0
- package/bottom-bar/types.js +2 -0
- package/box/index.d.ts +1 -1
- package/breakpoints.scss +1 -1
- package/button/button.module.scss +70 -53
- package/button/index.d.ts +26 -41
- package/button/index.js +22 -46
- package/card/index.d.ts +2 -1
- package/card/index.js +23 -6
- package/card/slots.d.ts +17 -3
- package/card/slots.js +15 -13
- package/carousel/draggable.d.ts +7 -3
- package/carousel/draggable.js +10 -3
- package/carousel/helpers/draggable-event.d.ts +5 -2
- package/carousel/helpers/draggable-event.js +5 -0
- package/carousel/index.d.ts +1 -1
- package/carousel/index.js +24 -24
- package/checkbox/checkbox.module.scss +1 -0
- package/checkbox/index.d.ts +3 -3
- package/checkbox-field/index.d.ts +3 -0
- package/checkbox-field/index.js +3 -0
- package/clean-buttons/clean-buttons-util.scss +15 -0
- package/clean-buttons/clean-buttons.module.scss +5 -3
- package/clean-buttons/index.d.ts +16 -7
- package/clean-buttons/index.js +17 -14
- package/clean-buttons/types.d.ts +1 -1
- package/clean-buttons/utils.d.ts +5 -1
- package/clean-buttons/utils.js +4 -0
- package/{colors.d.ts → colors/index.d.ts} +1 -1
- package/{colors.js → colors/index.js} +0 -0
- package/dot-nav/index.d.ts +1 -1
- package/dropdown/index.d.ts +1 -0
- package/dropdown/utils.d.ts +19 -0
- package/dropdown/utils.js +45 -0
- package/dropdown-item/dropdown-item.module.scss +80 -15
- package/dropdown-item/index.d.ts +20 -9
- package/dropdown-item/index.js +12 -9
- package/dropdown-item/types.d.ts +3 -0
- package/dropdown-item/types.js +2 -0
- package/dropdown-item/utils.d.ts +45 -0
- package/dropdown-item/utils.js +89 -0
- package/expandable/utils.js +3 -3
- package/field-block/field-block.module.scss +155 -0
- package/field-block/index.d.ts +63 -0
- package/field-block/index.js +43 -0
- package/field-grid/index.d.ts +5 -4
- package/field-grid/index.js +1 -0
- package/helpers/bounds-of.d.ts +5 -1
- package/helpers/bounds-of.js +5 -0
- package/helpers/center-of.d.ts +4 -1
- package/helpers/center-of.js +8 -1
- package/helpers/create-container.d.ts +5 -2
- package/helpers/create-container.js +7 -2
- package/helpers/define-slots.d.ts +3 -3
- package/helpers/define-slots.js +5 -3
- package/helpers/events.d.ts +16 -8
- package/helpers/events.js +41 -15
- package/helpers/find-child-element.d.ts +12 -9
- package/helpers/find-child-element.js +9 -5
- package/helpers/find-offset-parent.d.ts +1 -2
- package/helpers/find-offset-parent.js +2 -2
- package/helpers/find-sibling-index.d.ts +11 -8
- package/helpers/find-sibling-index.js +8 -3
- package/helpers/fit-element-height.d.ts +5 -5
- package/helpers/fit-element-height.js +9 -7
- package/helpers/format-date.d.ts +11 -11
- package/helpers/format-date.js +15 -13
- package/helpers/format-number.d.ts +1 -1
- package/helpers/format-number.js +2 -2
- package/helpers/get-date-interval-data.d.ts +4 -1
- package/helpers/get-date-interval-data.js +7 -2
- package/helpers/get-declination.d.ts +5 -1
- package/helpers/get-declination.js +5 -0
- package/helpers/get-fraction-depth.d.ts +1 -1
- package/helpers/get-fraction-depth.js +2 -2
- package/helpers/get-no-index.d.ts +2 -2
- package/helpers/get-no-index.js +4 -3
- package/helpers/get-relative-pos.d.ts +4 -1
- package/helpers/get-relative-pos.js +7 -2
- package/helpers/get-scroll-parent.d.ts +1 -2
- package/helpers/get-scroll-parent.js +5 -5
- package/helpers/is-browser.d.ts +4 -1
- package/helpers/is-browser.js +8 -1
- package/helpers/is-fully-scrolled.d.ts +3 -3
- package/helpers/is-fully-scrolled.js +2 -2
- package/helpers/is-touch-device.d.ts +1 -1
- package/helpers/is-touch-device.js +4 -5
- package/helpers/layer.d.ts +1 -1
- package/helpers/layer.js +2 -2
- package/helpers/max-index-of.d.ts +4 -1
- package/helpers/max-index-of.js +7 -2
- package/helpers/media-query-list.d.ts +1 -1
- package/helpers/media-query-list.js +2 -2
- package/helpers/on.d.ts +4 -1
- package/helpers/on.js +7 -2
- package/helpers/point.d.ts +4 -1
- package/helpers/point.js +8 -1
- package/helpers/rename.d.ts +3 -1
- package/helpers/rename.js +1 -0
- package/helpers/scroll-to-child.d.ts +1 -1
- package/helpers/scroll-to-child.js +3 -2
- package/helpers/styles.d.ts +8 -2
- package/helpers/styles.js +18 -4
- package/helpers/with-prevent.d.ts +9 -6
- package/helpers/with-prevent.js +16 -9
- package/hint/hint-view.d.ts +26 -0
- package/hint/hint-view.js +43 -0
- package/hint/hint-view.module.scss +31 -0
- package/hint/hint.d.ts +14 -0
- package/hint/hint.js +41 -0
- package/hint/index.d.ts +5 -8
- package/hint/index.js +13 -48
- package/hint/utils.d.ts +61 -0
- package/hint/utils.js +161 -0
- package/{hint → hint-deprecated}/hint.module.scss +0 -0
- package/hint-deprecated/index.d.ts +11 -0
- package/hint-deprecated/index.js +53 -0
- package/hooks/breakpoint/index.d.ts +7 -4
- package/hooks/breakpoint/index.js +21 -13
- package/hooks/breakpoint/types.d.ts +3 -4
- package/hooks/breakpoint/utils.d.ts +2 -1
- package/hooks/breakpoint/utils.js +2 -1
- package/hooks/index.d.ts +8 -8
- package/hooks/index.js +27 -19
- package/hooks/intersection/test-utils.d.ts +1 -1
- package/hooks/intersection/test-utils.js +2 -1
- package/hooks/styles.d.ts +6 -0
- package/hooks/styles.js +26 -0
- package/info-text/index.d.ts +23 -0
- package/info-text/index.js +60 -0
- package/info-text/info-text.module.scss +28 -0
- package/input/index.d.ts +32 -0
- package/input/index.js +96 -0
- package/input/input.module.scss +20 -0
- package/input/utils.d.ts +36 -0
- package/input/utils.js +71 -0
- package/layout/index.d.ts +6 -11
- package/layout/index.js +6 -60
- package/layout/layout.d.ts +10 -0
- package/layout/layout.js +32 -0
- package/layout/layout.module.scss +33 -26
- package/layout/legacy.d.ts +15 -0
- package/layout/legacy.js +68 -0
- package/layout/legacy.module.scss +49 -0
- package/layout/types.d.ts +6 -0
- package/layout/types.js +2 -0
- package/link/index.d.ts +4 -1
- package/link/index.js +2 -2
- package/link/link.module.scss +10 -0
- package/loading-overlay/index.d.ts +1 -0
- package/loading-overlay/index.js +1 -0
- package/masked-field/index.d.ts +1 -0
- package/masked-field/index.js +1 -0
- package/masked-input/hook.d.ts +8 -0
- package/masked-input/hook.js +72 -0
- package/masked-input/index.d.ts +5 -0
- package/masked-input/index.js +7 -0
- package/masked-input/masked-input.d.ts +8 -0
- package/masked-input/masked-input.js +73 -0
- package/masked-input/types.d.ts +51 -0
- package/masked-input/types.js +2 -0
- package/masked-input/utils.d.ts +15 -0
- package/masked-input/utils.js +49 -0
- package/modal/index.d.ts +10 -12
- package/modal/index.js +27 -64
- package/modal/modal.module.scss +98 -55
- package/modal/slots.d.ts +13 -10
- package/modal/slots.js +30 -28
- package/modal/utils.d.ts +8 -10
- package/modal/utils.js +2 -26
- package/modal-overlay/index.d.ts +13 -0
- package/modal-overlay/index.js +60 -0
- package/modal-overlay/modal-overlay-util.scss +1 -0
- package/modal-overlay/modal-overlay.module.scss +14 -0
- package/modal-overlay/utils.d.ts +14 -0
- package/modal-overlay/utils.js +32 -0
- package/package.json +49 -41
- package/pagination/utils.d.ts +2 -2
- package/panel/index.d.ts +27 -13
- package/panel/index.js +43 -9
- package/panel/panel.module.scss +49 -8
- package/phone-input/index.d.ts +4 -28
- package/phone-input/index.js +2 -121
- package/phone-input/phone-input.d.ts +8 -0
- package/phone-input/phone-input.js +133 -0
- package/phone-input/phone-input.module.scss +8 -32
- package/phone-input/presets.d.ts +21 -22
- package/phone-input/presets.js +1 -2
- package/phone-input/types.d.ts +6 -0
- package/phone-input/types.js +2 -0
- package/phone-input/utils.d.ts +30 -1
- package/phone-input/utils.js +52 -3
- package/phone-input-deprecated/index.d.ts +29 -0
- package/phone-input-deprecated/index.js +124 -0
- package/phone-input-deprecated/phone-input.module.scss +41 -0
- package/plate/index.d.ts +3 -3
- package/plate/index.js +2 -2
- package/plate/plate.module.scss +3 -0
- package/popup/index.d.ts +5 -0
- package/popup/index.js +12 -0
- package/popup/popup-view.d.ts +14 -0
- package/popup/popup-view.js +35 -0
- package/popup/popup-view.module.scss +40 -0
- package/popup/popup.d.ts +17 -0
- package/popup/popup.js +73 -0
- package/popup/utils.d.ts +38 -0
- package/popup/utils.js +83 -0
- package/price/index.d.ts +1 -1
- package/price/index.js +3 -3
- package/price/utils.d.ts +5 -5
- package/price/utils.js +33 -23
- package/radio-button/index.d.ts +10 -0
- package/radio-button/index.js +33 -0
- package/radio-button/radio-button.module.scss +46 -0
- package/rating/index.d.ts +2 -1
- package/rating/types.d.ts +1 -1
- package/readme.md +34 -41
- package/screen/index.d.ts +4 -2
- package/screen/index.js +34 -3
- package/screen/screen.module.scss +0 -2
- package/screen/slots.d.ts +2 -8
- package/screen/slots.js +8 -9
- package/screen/utils.d.ts +2 -1
- package/select/index.d.ts +2 -33
- package/select/index.js +3 -109
- package/select/parts/block.d.ts +8 -0
- package/select/parts/block.js +70 -0
- package/select/parts/block.module.scss +3 -0
- package/select/parts/button.d.ts +8 -0
- package/select/parts/button.js +69 -0
- package/select/parts/menu.d.ts +8 -0
- package/select/parts/menu.js +105 -0
- package/select/parts/menu.module.scss +4 -0
- package/select/select.d.ts +14 -0
- package/select/select.js +145 -0
- package/select/types.d.ts +55 -0
- package/select/types.js +2 -0
- package/select/utils.d.ts +3 -0
- package/select/utils.js +13 -0
- package/select-deprecated/index.d.ts +34 -0
- package/select-deprecated/index.js +112 -0
- package/{select → select-deprecated}/select.module.scss +0 -0
- package/shadows.scss +18 -0
- package/side-page/index.d.ts +11 -26
- package/side-page/index.js +21 -26
- package/side-page/side-page.module.scss +35 -29
- package/side-page/slots.d.ts +12 -20
- package/side-page/slots.js +16 -28
- package/spinner/index.d.ts +18 -6
- package/spinner/index.js +25 -12
- package/spinner/spinner.module.scss +8 -0
- package/stepper/index.d.ts +18 -10
- package/stepper/index.js +17 -8
- package/stepper/stepper.module.scss +14 -15
- package/styling/fonts.d.ts +3 -3
- package/switcher-row/index.d.ts +42 -0
- package/switcher-row/index.js +59 -0
- package/switcher-row/switcher-row.module.scss +55 -0
- package/text/index.d.ts +1 -1
- package/text-button/index.d.ts +42 -0
- package/text-button/index.js +46 -0
- package/text-button/text-button.module.scss +99 -0
- package/text-field/index.d.ts +7 -6
- package/text-field/index.js +3 -2
- package/textarea/index.d.ts +21 -0
- package/textarea/index.js +85 -0
- package/textarea/textarea.module.scss +15 -0
- package/toggle/index.d.ts +3 -3
- package/toggle/toggle.module.scss +17 -8
- package/tooltip/index.d.ts +1 -0
- package/tooltip/index.js +1 -0
- package/top-bar/index.d.ts +3 -40
- package/top-bar/index.js +4 -60
- package/top-bar/top-bar-util.scss +29 -0
- package/top-bar/top-bar.d.ts +9 -0
- package/top-bar/top-bar.js +101 -0
- package/top-bar/top-bar.module.scss +129 -67
- package/top-bar/types.d.ts +31 -0
- package/top-bar/types.js +2 -0
- package/top-bar/utils.d.ts +14 -0
- package/top-bar/utils.js +56 -0
- package/touch-slider/index.d.ts +1 -0
- package/touch-slider/index.js +3 -2
- package/types.d.ts +18 -0
- package/types.js +2 -0
- package/unknown-content/index.d.ts +3 -3
- package/unknown-content/index.js +3 -3
- package/unknown-content/unknown-content.module.scss +16 -12
- package/upload-area/index.d.ts +2 -0
- package/upload-area/index.js +5 -0
- package/upload-area/types.d.ts +32 -0
- package/upload-area/types.js +2 -0
- package/upload-area/upload-area-util.scss +17 -0
- package/upload-area/upload-area.d.ts +8 -0
- package/upload-area/upload-area.js +105 -0
- package/upload-area/upload-area.module.scss +78 -0
- package/{upload → upload-area}/upload.svg +0 -0
- package/upload-area/utils.d.ts +17 -0
- package/upload-area/utils.js +48 -0
- package/utils.scss +74 -1
- package/with-hint/index.d.ts +3 -2
- package/with-hint/index.js +1 -0
- package/with-hint/positioning-hint.d.ts +1 -1
- package/with-hint/positioning-hint.js +2 -2
- package/with-tooltip/index.d.ts +2 -1
- package/with-tooltip/index.js +1 -0
- package/with-tooltip/utils.d.ts +2 -2
- package/_internal/body-scroll.d.ts +0 -23
- package/_internal/body-scroll.js +0 -41
- package/_internal/checkbox/index.d.ts +0 -5
- package/constants.d.ts +0 -6
- package/constants.js +0 -9
- package/nav-bar/index.d.ts +0 -46
- package/nav-bar/index.js +0 -76
- package/nav-bar/nav-bar.module.scss +0 -95
- package/upload/area.d.ts +0 -25
- package/upload/area.js +0 -65
- package/upload/area.module.scss +0 -44
- package/upload/utils.d.ts +0 -29
- package/upload/utils.js +0 -45
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
|
+
var t = {};
|
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
28
|
+
t[p] = s[p];
|
|
29
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
30
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
31
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
32
|
+
t[p[i]] = s[p[i]];
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
};
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.PhoneInput = void 0;
|
|
41
|
+
const react_1 = __importStar(require("react"));
|
|
42
|
+
const dropdown_item_1 = require("../dropdown-item");
|
|
43
|
+
const hooks_1 = require("../hooks");
|
|
44
|
+
const masked_input_1 = require("../masked-input");
|
|
45
|
+
const presets_1 = require("./presets");
|
|
46
|
+
const utils_1 = require("./utils");
|
|
47
|
+
const select_1 = require("../select");
|
|
48
|
+
const utils_2 = require("../select/utils");
|
|
49
|
+
const up_1 = __importDefault(require("@sima-land/ui-quarks/icons/16x16/Stroked/Arrows/up"));
|
|
50
|
+
const down_1 = __importDefault(require("@sima-land/ui-quarks/icons/16x16/Stroked/Arrows/down"));
|
|
51
|
+
const bind_1 = __importDefault(require("classnames/bind"));
|
|
52
|
+
const phone_input_module_scss_1 = __importDefault(require("./phone-input.module.scss"));
|
|
53
|
+
const cx = bind_1.default.bind(phone_input_module_scss_1.default);
|
|
54
|
+
/**
|
|
55
|
+
* Поле ввода номера телефона.
|
|
56
|
+
* @param props Свойства.
|
|
57
|
+
* @return Элемент.
|
|
58
|
+
*/
|
|
59
|
+
function PhoneInput(_a) {
|
|
60
|
+
var _b;
|
|
61
|
+
var { value, defaultValue, label = 'Телефон', inputRef: inputRefProp, blockRef: blockRefProp, onBlur, onChange, onFocus, onCountrySelect, 'data-testid': testId = 'phone-input' } = _a, props = __rest(_a, ["value", "defaultValue", "label", "inputRef", "blockRef", "onBlur", "onChange", "onFocus", "onCountrySelect", 'data-testid']);
|
|
62
|
+
const firstRenderRef = (0, react_1.useRef)(true);
|
|
63
|
+
const [initialValue] = (0, react_1.useState)((_b = value !== null && value !== void 0 ? value : defaultValue) !== null && _b !== void 0 ? _b : '');
|
|
64
|
+
const [country, setCountry] = (0, react_1.useState)(() => (0, utils_1.defineCountry)(initialValue));
|
|
65
|
+
const [cleanValue, setCleanValue] = (0, react_1.useState)(() => utils_1.PhoneValue.removeCode(initialValue, country));
|
|
66
|
+
const inputRef = (0, react_1.useRef)(null);
|
|
67
|
+
(0, react_1.useImperativeHandle)(inputRefProp, () => inputRef.current);
|
|
68
|
+
const blockRef = (0, react_1.useRef)(null);
|
|
69
|
+
(0, react_1.useImperativeHandle)(blockRefProp, () => blockRef.current);
|
|
70
|
+
(0, hooks_1.useIsomorphicLayoutEffect)(() => {
|
|
71
|
+
if (typeof value !== 'undefined') {
|
|
72
|
+
setCleanValue(utils_1.PhoneValue.removeCode(value, country));
|
|
73
|
+
}
|
|
74
|
+
}, [value]);
|
|
75
|
+
const dispatchCountryChange = (0, react_1.useCallback)((input) => {
|
|
76
|
+
const nativeEvent = new Event('input');
|
|
77
|
+
const syntheticEvent = (0, utils_1.stubSyntheticEvent)(input, nativeEvent);
|
|
78
|
+
// @todo перенести вызов onChange в callback onValueChange если будет необходим preventDefault() и тд
|
|
79
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(syntheticEvent, {
|
|
80
|
+
value: input.value,
|
|
81
|
+
cleanValue: utils_1.PhoneValue.addCode('', country),
|
|
82
|
+
completed: false,
|
|
83
|
+
});
|
|
84
|
+
onCountrySelect === null || onCountrySelect === void 0 ? void 0 : onCountrySelect(country);
|
|
85
|
+
}, [onChange, onCountrySelect, country]);
|
|
86
|
+
(0, hooks_1.useIsomorphicLayoutEffect)(() => {
|
|
87
|
+
if (!firstRenderRef.current) {
|
|
88
|
+
inputRef.current && dispatchCountryChange(inputRef.current);
|
|
89
|
+
}
|
|
90
|
+
}, [country]);
|
|
91
|
+
(0, hooks_1.useIsomorphicLayoutEffect)(() => {
|
|
92
|
+
firstRenderRef.current = false;
|
|
93
|
+
}, []);
|
|
94
|
+
const processData = (0, react_1.useCallback)((data) => (Object.assign(Object.assign({}, data), { completed: data.completed || country.id === presets_1.IDS.other, cleanValue: utils_1.PhoneValue.addCode(data.cleanValue, country) })), [country]);
|
|
95
|
+
const changeCountry = (0, react_1.useCallback)((selected) => {
|
|
96
|
+
setCountry(selected);
|
|
97
|
+
setCleanValue('');
|
|
98
|
+
}, []);
|
|
99
|
+
return (react_1.default.createElement(select_1.Select, { opener: react_1.default.createElement(PhoneMaskedInput, Object.assign({}, props, { "data-testid": testId, country: country, inputRef: inputRef, blockRef: blockRef, label: label, mask: country.mask, onFocus: (event, data) => {
|
|
100
|
+
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event, processData(data));
|
|
101
|
+
}, onChange: (event, data) => {
|
|
102
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(event, processData(data));
|
|
103
|
+
}, onBlur: (event, data) => {
|
|
104
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event, processData(data));
|
|
105
|
+
}, value: cleanValue })), onValueChange: itemValue => {
|
|
106
|
+
const item = presets_1.countriesList.find(c => c.id === itemValue);
|
|
107
|
+
item && changeCountry(item);
|
|
108
|
+
} }, presets_1.countriesList.map((item, index) => (react_1.default.createElement(dropdown_item_1.DropdownItem, { value: item.id, key: index, size: 'm', role: 'menuitem', onMouseDown: event => {
|
|
109
|
+
// ВАЖНО: клик по блоку поля вызывает фокус на поле и preventDefault()
|
|
110
|
+
// отменяем с помощью другого preventDefault()
|
|
111
|
+
event.preventDefault();
|
|
112
|
+
}, selected: item.id === country.id, startContent: react_1.default.createElement("img", { alt: '', width: 24, height: 24, src: item.imageSrc }), endContent: item.code }, item.name)))));
|
|
113
|
+
}
|
|
114
|
+
exports.PhoneInput = PhoneInput;
|
|
115
|
+
/**
|
|
116
|
+
* Внутренний компонент, необходим для использования контекста SelectContext.
|
|
117
|
+
* @param props Свойства.
|
|
118
|
+
* @return Элемент.
|
|
119
|
+
*/
|
|
120
|
+
function PhoneMaskedInput(_a) {
|
|
121
|
+
var { country, blockRef: blockRefProp } = _a, props = __rest(_a, ["country", "blockRef"]);
|
|
122
|
+
const select = (0, react_1.useContext)(utils_2.SelectContext);
|
|
123
|
+
const blockRef = (0, react_1.useRef)(null);
|
|
124
|
+
const [openerFocused, setOpenerFocused] = (0, react_1.useState)(false);
|
|
125
|
+
(0, react_1.useImperativeHandle)(blockRefProp, () => blockRef.current);
|
|
126
|
+
(0, react_1.useImperativeHandle)(select.anchorRef, () => blockRef.current);
|
|
127
|
+
const ArrowSVG = select.opened ? up_1.default : down_1.default;
|
|
128
|
+
return (react_1.default.createElement(masked_input_1.MaskedInput, Object.assign({}, props, {
|
|
129
|
+
// ВАЖНО: undefined нужен для поведения по умолчанию если меню скрыто и кнопка не в фокусе
|
|
130
|
+
focused: select.opened || openerFocused || undefined, blockRef: blockRef, baseInputProps: Object.assign({ restPlaceholder: country.id === presets_1.IDS.other ? '' : undefined }, props.baseInputProps), adornmentEnd: react_1.default.createElement("div", { ref: select.openerRef, tabIndex: 0, onFocus: () => setOpenerFocused(true), onBlur: () => setOpenerFocused(false), role: 'combobox', "aria-label": '\u0412\u044B\u0431\u043E\u0440 \u0441\u0442\u0440\u0430\u043D\u044B', className: cx('opener'), "data-testid": 'phone-input:menu-opener', onKeyDown: select.onKeyDown, onMouseDown: select.onMouseDown },
|
|
131
|
+
react_1.default.createElement("img", { alt: '', width: 24, height: 24, src: country.imageSrc }),
|
|
132
|
+
react_1.default.createElement(ArrowSVG, { className: phone_input_module_scss_1.default.arrow })) })));
|
|
133
|
+
}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
@use '../colors';
|
|
2
2
|
|
|
3
|
-
.
|
|
4
|
-
text-align: left;
|
|
5
|
-
position: relative;
|
|
6
|
-
width: var(--phone-input-width, 320px);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.field {
|
|
10
|
-
width: 100%;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.adornment {
|
|
3
|
+
.opener {
|
|
14
4
|
display: flex;
|
|
15
5
|
align-items: center;
|
|
16
6
|
user-select: none;
|
|
17
7
|
cursor: pointer;
|
|
8
|
+
padding: 8px;
|
|
9
|
+
margin: -8px;
|
|
10
|
+
border-radius: 4px;
|
|
11
|
+
&:focus-visible {
|
|
12
|
+
outline: 0;
|
|
13
|
+
background: colors.$additional-sky;
|
|
14
|
+
}
|
|
18
15
|
}
|
|
19
16
|
|
|
20
17
|
.arrow {
|
|
@@ -23,24 +20,3 @@
|
|
|
23
20
|
margin-left: 4px;
|
|
24
21
|
pointer-events: none; // игнорируем клики т.к. после них элемент стрелки подменяется и считается что он сработал вне элемента родителя
|
|
25
22
|
}
|
|
26
|
-
|
|
27
|
-
.menu {
|
|
28
|
-
position: absolute;
|
|
29
|
-
width: 100%;
|
|
30
|
-
top: 56px;
|
|
31
|
-
--dropdown-max-height: 208px;
|
|
32
|
-
z-index: 2;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.menu-item {
|
|
36
|
-
font-size: 16px;
|
|
37
|
-
line-height: 24px;
|
|
38
|
-
.item-name {
|
|
39
|
-
color: colors.$basic-gray87;
|
|
40
|
-
flex-grow: 1;
|
|
41
|
-
margin-left: 16px;
|
|
42
|
-
}
|
|
43
|
-
.item-code {
|
|
44
|
-
color: colors.$basic-gray38;
|
|
45
|
-
}
|
|
46
|
-
}
|
package/phone-input/presets.d.ts
CHANGED
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
/// <reference types="lodash" />
|
|
2
1
|
export interface Country {
|
|
3
|
-
id: string;
|
|
4
|
-
name: string;
|
|
5
|
-
code: string;
|
|
6
|
-
codeChars: string;
|
|
7
|
-
mask: string;
|
|
8
|
-
imageSrc: string;
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly code: string;
|
|
5
|
+
readonly codeChars: string;
|
|
6
|
+
readonly mask: string;
|
|
7
|
+
readonly imageSrc: string;
|
|
9
8
|
}
|
|
10
9
|
export declare const IDS: {
|
|
11
|
-
russia:
|
|
12
|
-
kazakhstan:
|
|
13
|
-
armenia:
|
|
14
|
-
belarus:
|
|
15
|
-
kyrgyzstan:
|
|
16
|
-
azerbaijan:
|
|
17
|
-
georgia:
|
|
18
|
-
moldova:
|
|
19
|
-
tajikistan:
|
|
20
|
-
turkmenistan:
|
|
21
|
-
uzbekistan:
|
|
22
|
-
ukraine:
|
|
23
|
-
other:
|
|
10
|
+
readonly russia: "russia";
|
|
11
|
+
readonly kazakhstan: "kazakhstan";
|
|
12
|
+
readonly armenia: "armenia";
|
|
13
|
+
readonly belarus: "belarus";
|
|
14
|
+
readonly kyrgyzstan: "kyrgyzstan";
|
|
15
|
+
readonly azerbaijan: "azerbaijan";
|
|
16
|
+
readonly georgia: "georgia";
|
|
17
|
+
readonly moldova: "moldova";
|
|
18
|
+
readonly tajikistan: "tajikistan";
|
|
19
|
+
readonly turkmenistan: "turkmenistan";
|
|
20
|
+
readonly uzbekistan: "uzbekistan";
|
|
21
|
+
readonly ukraine: "ukraine";
|
|
22
|
+
readonly other: "other";
|
|
24
23
|
};
|
|
25
|
-
export declare const countriesList: Country
|
|
26
|
-
export declare const countries:
|
|
24
|
+
export declare const countriesList: ReadonlyArray<Country>;
|
|
25
|
+
export declare const countries: Readonly<Record<string, Country>>;
|
package/phone-input/presets.js
CHANGED
|
@@ -17,7 +17,6 @@ const turkmenistan_png_1 = __importDefault(require("./images/turkmenistan.png"))
|
|
|
17
17
|
const uzbekistan_png_1 = __importDefault(require("./images/uzbekistan.png"));
|
|
18
18
|
const ukraine_png_1 = __importDefault(require("./images/ukraine.png"));
|
|
19
19
|
const other_png_1 = __importDefault(require("./images/other.png"));
|
|
20
|
-
const lodash_1 = require("lodash");
|
|
21
20
|
exports.IDS = {
|
|
22
21
|
russia: 'russia',
|
|
23
22
|
kazakhstan: 'kazakhstan',
|
|
@@ -116,4 +115,4 @@ exports.countriesList = ORDER.map(id => ({
|
|
|
116
115
|
mask: MASKS[id],
|
|
117
116
|
imageSrc: IMAGES[id],
|
|
118
117
|
}));
|
|
119
|
-
exports.countries = (
|
|
118
|
+
exports.countries = exports.countriesList.reduce((acc, item) => (Object.assign(Object.assign({}, acc), { [item.id]: item })), {});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MaskedInputProps } from '../masked-input';
|
|
2
|
+
import { Country } from './presets';
|
|
3
|
+
export interface PhoneInputProps extends Omit<MaskedInputProps, 'mask' | 'placeholder' | 'pattern'> {
|
|
4
|
+
/** Сработает при выборе страны из выпадающего списка. */
|
|
5
|
+
onCountrySelect?: (country: Country) => void;
|
|
6
|
+
}
|
package/phone-input/utils.d.ts
CHANGED
|
@@ -1,7 +1,36 @@
|
|
|
1
|
+
import { SyntheticEvent } from 'react';
|
|
1
2
|
import { Country } from './presets';
|
|
2
3
|
/**
|
|
3
4
|
* Определяет страну по номеру телефона.
|
|
4
5
|
* @param value Значение.
|
|
5
6
|
* @return Данные маски страны.
|
|
6
7
|
*/
|
|
7
|
-
export declare
|
|
8
|
+
export declare function defineCountry(value: string): Country;
|
|
9
|
+
/**
|
|
10
|
+
* Утилиты для работы со строкой, представляющей номер телефона.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PhoneValue: {
|
|
13
|
+
/**
|
|
14
|
+
* Получив номер без кода страны и страну вернет номер с кодом.
|
|
15
|
+
* @param value Номер.
|
|
16
|
+
* @param country Страна.
|
|
17
|
+
* @return Номер.
|
|
18
|
+
*/
|
|
19
|
+
readonly addCode: (value: string, country: Country) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Получив номер с кодом страны и страну вернет номер без кода.
|
|
22
|
+
* @param value Номер.
|
|
23
|
+
* @param country Страна.
|
|
24
|
+
* @return Номер.
|
|
25
|
+
*/
|
|
26
|
+
readonly removeCode: (value: string, country: Country) => string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Заглушка для вызова callback'ов которые ожидают SyntheticEvent.
|
|
30
|
+
* @param element Элемент.
|
|
31
|
+
* @param nativeEvent Событие.
|
|
32
|
+
* @return Синтетическое событие.
|
|
33
|
+
*/
|
|
34
|
+
export declare function stubSyntheticEvent<T extends Element, E extends Event>(element: T, nativeEvent: E): SyntheticEvent<T, E> & {
|
|
35
|
+
target: EventTarget & T;
|
|
36
|
+
};
|
package/phone-input/utils.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defineCountry = void 0;
|
|
3
|
+
exports.stubSyntheticEvent = exports.PhoneValue = exports.defineCountry = void 0;
|
|
4
4
|
const presets_1 = require("./presets");
|
|
5
5
|
/**
|
|
6
6
|
* Определяет страну по номеру телефона.
|
|
7
7
|
* @param value Значение.
|
|
8
8
|
* @return Данные маски страны.
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
function defineCountry(value) {
|
|
11
11
|
let result;
|
|
12
12
|
if (value) {
|
|
13
13
|
result = presets_1.countriesList.find(({ codeChars }) => value.indexOf(codeChars) === 0);
|
|
@@ -16,5 +16,54 @@ const defineCountry = (value) => {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
return result || presets_1.countries.russia;
|
|
19
|
-
}
|
|
19
|
+
}
|
|
20
20
|
exports.defineCountry = defineCountry;
|
|
21
|
+
/**
|
|
22
|
+
* Утилиты для работы со строкой, представляющей номер телефона.
|
|
23
|
+
*/
|
|
24
|
+
exports.PhoneValue = {
|
|
25
|
+
/**
|
|
26
|
+
* Получив номер без кода страны и страну вернет номер с кодом.
|
|
27
|
+
* @param value Номер.
|
|
28
|
+
* @param country Страна.
|
|
29
|
+
* @return Номер.
|
|
30
|
+
*/
|
|
31
|
+
addCode(value, country) {
|
|
32
|
+
return `${country.codeChars}${value.replace(/\D/g, '')}`;
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Получив номер с кодом страны и страну вернет номер без кода.
|
|
36
|
+
* @param value Номер.
|
|
37
|
+
* @param country Страна.
|
|
38
|
+
* @return Номер.
|
|
39
|
+
*/
|
|
40
|
+
removeCode(value, country) {
|
|
41
|
+
return value.replace(/\D/g, '').slice(country.codeChars.length);
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Заглушка для вызова callback'ов которые ожидают SyntheticEvent.
|
|
46
|
+
* @param element Элемент.
|
|
47
|
+
* @param nativeEvent Событие.
|
|
48
|
+
* @return Синтетическое событие.
|
|
49
|
+
*/
|
|
50
|
+
function stubSyntheticEvent(element, nativeEvent) {
|
|
51
|
+
return {
|
|
52
|
+
nativeEvent,
|
|
53
|
+
currentTarget: element,
|
|
54
|
+
target: element,
|
|
55
|
+
type: nativeEvent.type,
|
|
56
|
+
bubbles: nativeEvent.bubbles,
|
|
57
|
+
cancelable: nativeEvent.cancelable,
|
|
58
|
+
eventPhase: nativeEvent.eventPhase,
|
|
59
|
+
isTrusted: nativeEvent.isTrusted,
|
|
60
|
+
timeStamp: nativeEvent.timeStamp,
|
|
61
|
+
defaultPrevented: false,
|
|
62
|
+
isDefaultPrevented: () => false,
|
|
63
|
+
isPropagationStopped: () => false,
|
|
64
|
+
persist: () => void 0,
|
|
65
|
+
preventDefault: () => void 0,
|
|
66
|
+
stopPropagation: () => void 0,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
exports.stubSyntheticEvent = stubSyntheticEvent;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TextFieldProps } from '../text-field';
|
|
3
|
+
import { MaskState } from '../masked-field';
|
|
4
|
+
import { Country } from '../phone-input/presets';
|
|
5
|
+
interface PhoneInputStyle extends React.CSSProperties {
|
|
6
|
+
'--phone-input-width'?: number | string;
|
|
7
|
+
}
|
|
8
|
+
export interface PhoneInputProps extends Omit<TextFieldProps, 'onChange' | 'onBlur' | 'value' | 'ref' | 'style' | 'multiline'> {
|
|
9
|
+
/** Сработает при "blur". */
|
|
10
|
+
onBlur?: (e: React.FocusEvent<HTMLInputElement>, s: MaskState & {
|
|
11
|
+
ready?: boolean;
|
|
12
|
+
}) => void;
|
|
13
|
+
/** Сработает при изменении поля "Другое". Не рекомендуется использовать. */
|
|
14
|
+
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
15
|
+
/** Срабатывает при изменении страны. */
|
|
16
|
+
onCountrySelect?: (c: Country) => void;
|
|
17
|
+
/** Значение. */
|
|
18
|
+
value?: string;
|
|
19
|
+
/** Стили. */
|
|
20
|
+
style?: PhoneInputStyle;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Компонент поля ввода номера телефона.
|
|
24
|
+
* @param props Параметры компонента.
|
|
25
|
+
* @deprecated Нужно использовать новую реализацию "@sima-land/ui-nucleons/phone-input".
|
|
26
|
+
* @return Элемент.
|
|
27
|
+
*/
|
|
28
|
+
export declare const PhoneInput: ({ "data-testid": testId, className, label, onBlur, onCountrySelect, style, value, onChange, ...restProps }: PhoneInputProps) => JSX.Element;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
26
|
+
var t = {};
|
|
27
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
28
|
+
t[p] = s[p];
|
|
29
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
30
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
31
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
32
|
+
t[p[i]] = s[p[i]];
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
};
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.PhoneInput = void 0;
|
|
41
|
+
const react_1 = __importStar(require("react"));
|
|
42
|
+
const down_1 = __importDefault(require("@sima-land/ui-quarks/icons/16x16/Stroked/Arrows/down"));
|
|
43
|
+
const up_1 = __importDefault(require("@sima-land/ui-quarks/icons/16x16/Stroked/Arrows/up"));
|
|
44
|
+
const dropdown_1 = require("../dropdown");
|
|
45
|
+
const dropdown_item_1 = require("../dropdown-item");
|
|
46
|
+
const text_field_1 = require("../text-field");
|
|
47
|
+
const masked_field_1 = require("../masked-field");
|
|
48
|
+
const hooks_1 = require("../hooks");
|
|
49
|
+
const presets_1 = require("../phone-input/presets");
|
|
50
|
+
const utils_1 = require("../phone-input/utils");
|
|
51
|
+
const bind_1 = __importDefault(require("classnames/bind"));
|
|
52
|
+
const phone_input_module_scss_1 = __importDefault(require("./phone-input.module.scss"));
|
|
53
|
+
const cx = bind_1.default.bind(phone_input_module_scss_1.default);
|
|
54
|
+
/**
|
|
55
|
+
* Удаляет из значения код переданной страны.
|
|
56
|
+
* @param value Значение.
|
|
57
|
+
* @param country Данные страны.
|
|
58
|
+
* @return Значение без кода.
|
|
59
|
+
*/
|
|
60
|
+
const formatValue = (value, country) => value.replace(/\D/g, '').slice(country.codeChars.length);
|
|
61
|
+
/**
|
|
62
|
+
* Компонент поля ввода номера телефона.
|
|
63
|
+
* @param props Параметры компонента.
|
|
64
|
+
* @deprecated Нужно использовать новую реализацию "@sima-land/ui-nucleons/phone-input".
|
|
65
|
+
* @return Элемент.
|
|
66
|
+
*/
|
|
67
|
+
const PhoneInput = (_a) => {
|
|
68
|
+
var { 'data-testid': testId, className, label = 'Телефон', onBlur, onCountrySelect, style, value = '', onChange } = _a, restProps = __rest(_a, ['data-testid', "className", "label", "onBlur", "onCountrySelect", "style", "value", "onChange"]);
|
|
69
|
+
// маску определяем автоматически только при старте
|
|
70
|
+
const [country, setCountry] = (0, react_1.useState)(() => (0, utils_1.defineCountry)(value));
|
|
71
|
+
const [cleanValue, setCleanValue] = (0, react_1.useState)(() => formatValue(value, country));
|
|
72
|
+
const [withMenu, toggleMenu] = (0, react_1.useState)(false);
|
|
73
|
+
const rootRef = (0, react_1.useRef)(null);
|
|
74
|
+
const openerRef = (0, react_1.useRef)(null);
|
|
75
|
+
(0, react_1.useEffect)(() => {
|
|
76
|
+
setCleanValue(formatValue(value, country));
|
|
77
|
+
}, [value]);
|
|
78
|
+
(0, hooks_1.useOutsideClick)(rootRef, () => {
|
|
79
|
+
toggleMenu(false);
|
|
80
|
+
});
|
|
81
|
+
const AdornmentSVG = withMenu ? up_1.default : down_1.default;
|
|
82
|
+
const commonFieldProps = Object.assign(Object.assign({}, restProps), { label, multiline: false, className: cx('field'), endAdornment: (react_1.default.createElement("div", { ref: openerRef, className: cx('adornment'), "data-testid": 'phone-input:dropdown-opener', onClick: () => {
|
|
83
|
+
toggleMenu(a => !a);
|
|
84
|
+
} },
|
|
85
|
+
react_1.default.createElement("img", { alt: '', width: 24, height: 24, src: country.imageSrc }),
|
|
86
|
+
react_1.default.createElement(AdornmentSVG, { className: cx('arrow') }))), onClick: event => {
|
|
87
|
+
const opener = openerRef.current;
|
|
88
|
+
if (opener instanceof Node &&
|
|
89
|
+
event.target instanceof Node &&
|
|
90
|
+
(opener === event.target || opener.contains(event.target))) {
|
|
91
|
+
event.preventDefault(); // чтобы не фокусировалось на поле
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
toggleMenu(false);
|
|
95
|
+
}
|
|
96
|
+
} });
|
|
97
|
+
return (react_1.default.createElement("div", { ref: rootRef, "data-testid": testId, style: style, className: cx('root', className) },
|
|
98
|
+
country.id === presets_1.IDS.other ? (react_1.default.createElement(text_field_1.TextField, Object.assign({}, commonFieldProps, { value: cleanValue, onChange: (e) => {
|
|
99
|
+
const nextValue = e.target.value.replace(/\D/g, '').slice(0, 20);
|
|
100
|
+
e.target.value = nextValue;
|
|
101
|
+
setCleanValue(nextValue);
|
|
102
|
+
onChange && onChange(e);
|
|
103
|
+
}, onBlur: e => {
|
|
104
|
+
onBlur &&
|
|
105
|
+
onBlur(e, {
|
|
106
|
+
value: e.target.value,
|
|
107
|
+
cleanValue: e.target.value,
|
|
108
|
+
ready: e.target.value.length > 0,
|
|
109
|
+
});
|
|
110
|
+
} }))) : (react_1.default.createElement(masked_field_1.MaskedField, Object.assign({}, commonFieldProps, {
|
|
111
|
+
// убираем код страны, так как он уже зашит в маску
|
|
112
|
+
value: cleanValue, mask: country.mask, onBlur: (event, state) => {
|
|
113
|
+
onBlur &&
|
|
114
|
+
onBlur(event, Object.assign(Object.assign({}, state), {
|
|
115
|
+
// вставляем код страны обратно в чистое значение
|
|
116
|
+
cleanValue: `${country.codeChars}${state.cleanValue}` }));
|
|
117
|
+
} }))),
|
|
118
|
+
withMenu && (react_1.default.createElement(dropdown_1.Dropdown, { role: 'menu', className: cx('menu'), "data-testid": 'phone-input:dropdown' }, presets_1.countriesList.map((item, index) => item.id === country.id ? null : (react_1.default.createElement(dropdown_item_1.DropdownItem, { key: index, size: 'm', role: 'menuitem', className: cx('menu-item'), onClick: () => {
|
|
119
|
+
toggleMenu(false);
|
|
120
|
+
setCountry(item);
|
|
121
|
+
onCountrySelect && onCountrySelect(item);
|
|
122
|
+
}, startContent: react_1.default.createElement("img", { alt: '', width: 24, height: 24, src: item.imageSrc, className: cx('country-icon') }), endContent: item.code }, item.name)))))));
|
|
123
|
+
};
|
|
124
|
+
exports.PhoneInput = PhoneInput;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
@use '../colors';
|
|
2
|
+
|
|
3
|
+
.root {
|
|
4
|
+
text-align: left;
|
|
5
|
+
position: relative;
|
|
6
|
+
width: var(--phone-input-width, 320px);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.field {
|
|
10
|
+
width: 100%;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.adornment {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
user-select: none;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.arrow {
|
|
21
|
+
display: block;
|
|
22
|
+
fill: colors.$basic-gray38;
|
|
23
|
+
margin-left: 4px;
|
|
24
|
+
pointer-events: none; // игнорируем клики т.к. после них элемент стрелки подменяется и считается что он сработал вне элемента родителя
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.menu {
|
|
28
|
+
position: absolute;
|
|
29
|
+
width: 100%;
|
|
30
|
+
top: 56px;
|
|
31
|
+
--dropdown-max-height: 208px;
|
|
32
|
+
z-index: 2;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.menu-item {
|
|
36
|
+
font-size: 16px;
|
|
37
|
+
line-height: 24px;
|
|
38
|
+
.country-icon {
|
|
39
|
+
display: block;
|
|
40
|
+
}
|
|
41
|
+
}
|
package/plate/index.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import { BoxShadow } from '../styling/shadows';
|
|
3
3
|
export interface PlateProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
/** Тень. */
|
|
5
|
-
shadow?: keyof typeof BoxShadow;
|
|
6
|
-
/**
|
|
7
|
-
rounds?: 's' | 'm';
|
|
5
|
+
shadow?: keyof typeof BoxShadow | null;
|
|
6
|
+
/** Скругление углов. */
|
|
7
|
+
rounds?: 's' | 'm' | null;
|
|
8
8
|
/** Идентификатор для систем автоматизированного тестирования. */
|
|
9
9
|
'data-testid'?: string;
|
|
10
10
|
}
|
package/plate/index.js
CHANGED
|
@@ -39,15 +39,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.Plate = void 0;
|
|
41
41
|
const react_1 = __importStar(require("react"));
|
|
42
|
-
const colors_1 = require("../styling/colors");
|
|
43
42
|
const shadows_1 = require("../styling/shadows");
|
|
44
43
|
const shapes_1 = require("../styling/shapes");
|
|
45
44
|
const classnames_1 = __importDefault(require("classnames"));
|
|
45
|
+
const plate_module_scss_1 = __importDefault(require("./plate.module.scss"));
|
|
46
46
|
/**
|
|
47
47
|
* Plate это просто div с возможностью легко задавать тень и скругления.
|
|
48
48
|
* И он должен оставаться компонентом, который только задает оформление обычного div.
|
|
49
49
|
*/
|
|
50
50
|
exports.Plate = (0, react_1.forwardRef)(function Plate(_a, ref) {
|
|
51
51
|
var { className, children, rounds = 's', shadow = 'z1', 'data-testid': testId = 'plate' } = _a, restProps = __rest(_a, ["className", "children", "rounds", "shadow", 'data-testid']);
|
|
52
|
-
return (react_1.default.createElement("div", Object.assign({ ref: ref, className: (0, classnames_1.default)(
|
|
52
|
+
return (react_1.default.createElement("div", Object.assign({ ref: ref, className: (0, classnames_1.default)(plate_module_scss_1.default.root, className, shadow && shadows_1.BoxShadow[shadow], rounds === 's' && shapes_1.SmallRounds.all, rounds === 'm' && shapes_1.MediumRounds.all), "data-testid": testId, children: children }, restProps)));
|
|
53
53
|
});
|
package/popup/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Popup, PopupProps } from './popup';
|
|
2
|
+
import { PopupView, PopupViewProps } from './popup-view';
|
|
3
|
+
import { popupFloatingConfig, usePopupFloatingStyle, usePopupOnClick, useFocusTrap } from './utils';
|
|
4
|
+
export type { PopupProps, PopupViewProps };
|
|
5
|
+
export { Popup, PopupView, popupFloatingConfig, usePopupFloatingStyle, usePopupOnClick, useFocusTrap, };
|
package/popup/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useFocusTrap = exports.usePopupOnClick = exports.usePopupFloatingStyle = exports.popupFloatingConfig = exports.PopupView = exports.Popup = void 0;
|
|
4
|
+
const popup_1 = require("./popup");
|
|
5
|
+
Object.defineProperty(exports, "Popup", { enumerable: true, get: function () { return popup_1.Popup; } });
|
|
6
|
+
const popup_view_1 = require("./popup-view");
|
|
7
|
+
Object.defineProperty(exports, "PopupView", { enumerable: true, get: function () { return popup_view_1.PopupView; } });
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
Object.defineProperty(exports, "popupFloatingConfig", { enumerable: true, get: function () { return utils_1.popupFloatingConfig; } });
|
|
10
|
+
Object.defineProperty(exports, "usePopupFloatingStyle", { enumerable: true, get: function () { return utils_1.usePopupFloatingStyle; } });
|
|
11
|
+
Object.defineProperty(exports, "usePopupOnClick", { enumerable: true, get: function () { return utils_1.usePopupOnClick; } });
|
|
12
|
+
Object.defineProperty(exports, "useFocusTrap", { enumerable: true, get: function () { return utils_1.useFocusTrap; } });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HTMLAttributes, Ref } from 'react';
|
|
2
|
+
import { WithTestId } from '../types';
|
|
3
|
+
export interface PopupViewProps extends HTMLAttributes<HTMLDivElement>, WithTestId {
|
|
4
|
+
/** Сработает при клике на крестик. */
|
|
5
|
+
onClose?: () => void;
|
|
6
|
+
/** Реф корневого элемента. */
|
|
7
|
+
popupRef?: Ref<HTMLDivElement>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Popup.
|
|
11
|
+
* @param props Свойства.
|
|
12
|
+
* @return Элемент.
|
|
13
|
+
*/
|
|
14
|
+
export declare function PopupView({ children, onClose, popupRef, className, 'data-testid': testId, ...rest }: PopupViewProps): JSX.Element;
|