@alfalab/core-components-pattern-lock 1.2.4 → 1.3.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/Component.js +4 -8
- package/cssm/Component.js +3 -7
- package/cssm/index.js +2 -1
- package/esm/Component.js +4 -8
- package/esm/index.css +10 -10
- package/esm/index.js +2 -1
- package/index.css +10 -10
- package/index.js +2 -1
- package/modern/Component.js +4 -8
- package/modern/index.css +10 -10
- package/modern/index.js +2 -1
- package/package.json +4 -3
- package/src/Component.tsx +114 -0
- package/src/consts.ts +30 -0
- package/src/index.module.css +54 -0
- package/src/index.ts +3 -0
- package/src/typings.ts +71 -0
- package/src/utils.ts +84 -0
- package/src/vars.css +3 -0
package/Component.js
CHANGED
|
@@ -6,8 +6,9 @@ var tslib = require('tslib');
|
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var reactCanvasPatternLock = require('react-canvas-pattern-lock');
|
|
8
8
|
var cn = require('classnames');
|
|
9
|
-
var
|
|
9
|
+
var mobile = require('@alfalab/core-components-button/mobile');
|
|
10
10
|
var coreComponentsGap = require('@alfalab/core-components-gap');
|
|
11
|
+
var coreComponentsShared = require('@alfalab/core-components-shared');
|
|
11
12
|
var consts = require('./consts.js');
|
|
12
13
|
var utils = require('./utils.js');
|
|
13
14
|
|
|
@@ -16,12 +17,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
|
|
|
16
17
|
var React__default = /*#__PURE__*/_interopDefaultCompat(React);
|
|
17
18
|
var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
|
|
18
19
|
|
|
19
|
-
var
|
|
20
|
-
var elementPart = element ? "-".concat(element.toLowerCase()) : '';
|
|
21
|
-
return dataTestId ? "".concat(dataTestId).concat(elementPart) : undefined;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
var styles = {"component":"pattern-lock__component_1an4o","hidden":"pattern-lock__hidden_1an4o","error":"pattern-lock__error_1an4o","forgotBtn":"pattern-lock__forgotBtn_1an4o"};
|
|
20
|
+
var styles = {"component":"pattern-lock__component_1g0p7","hidden":"pattern-lock__hidden_1g0p7","error":"pattern-lock__error_1g0p7","forgotBtn":"pattern-lock__forgotBtn_1g0p7"};
|
|
25
21
|
require('./index.css')
|
|
26
22
|
|
|
27
23
|
var PatternLock = React.forwardRef(function (_a, ref) {
|
|
@@ -63,7 +59,7 @@ var PatternLock = React.forwardRef(function (_a, ref) {
|
|
|
63
59
|
React__default.default.createElement("div", { className: styles.error }, error),
|
|
64
60
|
React__default.default.createElement(coreComponentsGap.Gap, { size: '3xl' }),
|
|
65
61
|
React__default.default.createElement(reactCanvasPatternLock.ReactCanvasPatternLock, tslib.__assign({}, restProps, params, { ref: ref, rows: 3, cols: 3, justifyNodes: justifyNodes, extraBounds: extraBounds })),
|
|
66
|
-
showForgotCodeBtn ? (React__default.default.createElement(
|
|
62
|
+
showForgotCodeBtn ? (React__default.default.createElement(mobile.ButtonMobile, { view: 'link', className: styles.forgotBtn, onClick: onForgotBtnClick, dataTestId: coreComponentsShared.getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React__default.default.createElement("div", { className: styles.forgotBtn }))));
|
|
67
63
|
});
|
|
68
64
|
|
|
69
65
|
exports.PatternLock = PatternLock;
|
package/cssm/Component.js
CHANGED
|
@@ -6,8 +6,9 @@ var tslib = require('tslib');
|
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var reactCanvasPatternLock = require('react-canvas-pattern-lock');
|
|
8
8
|
var cn = require('classnames');
|
|
9
|
-
var
|
|
9
|
+
var mobile = require('@alfalab/core-components-button/cssm/mobile');
|
|
10
10
|
var coreComponentsGap = require('@alfalab/core-components-gap/cssm');
|
|
11
|
+
var coreComponentsShared = require('@alfalab/core-components-shared/cssm');
|
|
11
12
|
var consts = require('./consts.js');
|
|
12
13
|
var utils = require('./utils.js');
|
|
13
14
|
var styles = require('./index.module.css');
|
|
@@ -18,11 +19,6 @@ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
|
|
|
18
19
|
var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
|
|
19
20
|
var styles__default = /*#__PURE__*/_interopDefaultCompat(styles);
|
|
20
21
|
|
|
21
|
-
var getDataTestId = function (dataTestId, element) {
|
|
22
|
-
var elementPart = element ? "-".concat(element.toLowerCase()) : '';
|
|
23
|
-
return dataTestId ? "".concat(dataTestId).concat(elementPart) : undefined;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
22
|
var PatternLock = React.forwardRef(function (_a, ref) {
|
|
27
23
|
var _b;
|
|
28
24
|
var _c = _a.observeTokens, observeTokens = _c === void 0 ? false : _c, _d = _a.observerParams, observerParams = _d === void 0 ? {} : _d, _e = _a.justifyNodes, justifyNodes = _e === void 0 ? 'space-between' : _e, className = _a.className, error = _a.error, dataTestId = _a.dataTestId, _f = _a.forgotCodeBtnText, forgotCodeBtnText = _f === void 0 ? 'Забыли код?' : _f, _g = _a.showForgotCodeBtn, showForgotCodeBtn = _g === void 0 ? false : _g, onForgotBtnClick = _a.onForgotBtnClick, _h = _a.extraBounds, extraBounds = _h === void 0 ? consts.DEFAULT_EXTRA_BOUNDS : _h, restProps = tslib.__rest(_a, ["observeTokens", "observerParams", "justifyNodes", "className", "error", "dataTestId", "forgotCodeBtnText", "showForgotCodeBtn", "onForgotBtnClick", "extraBounds"]);
|
|
@@ -62,7 +58,7 @@ var PatternLock = React.forwardRef(function (_a, ref) {
|
|
|
62
58
|
React__default.default.createElement("div", { className: styles__default.default.error }, error),
|
|
63
59
|
React__default.default.createElement(coreComponentsGap.Gap, { size: '3xl' }),
|
|
64
60
|
React__default.default.createElement(reactCanvasPatternLock.ReactCanvasPatternLock, tslib.__assign({}, restProps, params, { ref: ref, rows: 3, cols: 3, justifyNodes: justifyNodes, extraBounds: extraBounds })),
|
|
65
|
-
showForgotCodeBtn ? (React__default.default.createElement(
|
|
61
|
+
showForgotCodeBtn ? (React__default.default.createElement(mobile.ButtonMobile, { view: 'link', className: styles__default.default.forgotBtn, onClick: onForgotBtnClick, dataTestId: coreComponentsShared.getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React__default.default.createElement("div", { className: styles__default.default.forgotBtn }))));
|
|
66
62
|
});
|
|
67
63
|
|
|
68
64
|
exports.PatternLock = PatternLock;
|
package/cssm/index.js
CHANGED
|
@@ -8,8 +8,9 @@ require('tslib');
|
|
|
8
8
|
require('react');
|
|
9
9
|
require('react-canvas-pattern-lock');
|
|
10
10
|
require('classnames');
|
|
11
|
-
require('@alfalab/core-components-button/cssm');
|
|
11
|
+
require('@alfalab/core-components-button/cssm/mobile');
|
|
12
12
|
require('@alfalab/core-components-gap/cssm');
|
|
13
|
+
require('@alfalab/core-components-shared/cssm');
|
|
13
14
|
require('./utils.js');
|
|
14
15
|
require('./index.module.css');
|
|
15
16
|
|
package/esm/Component.js
CHANGED
|
@@ -2,17 +2,13 @@ import { __rest, __assign } from 'tslib';
|
|
|
2
2
|
import React, { forwardRef, useState, useEffect } from 'react';
|
|
3
3
|
import { ReactCanvasPatternLock } from 'react-canvas-pattern-lock';
|
|
4
4
|
import cn from 'classnames';
|
|
5
|
-
import {
|
|
5
|
+
import { ButtonMobile } from '@alfalab/core-components-button/esm/mobile';
|
|
6
6
|
import { Gap } from '@alfalab/core-components-gap/esm';
|
|
7
|
+
import { getDataTestId } from '@alfalab/core-components-shared/esm';
|
|
7
8
|
import { THEME_STATE, DEFAULT_EXTRA_BOUNDS, OBSERVE_OPTIONS, OBSERVABLE_TOKENS } from './consts.js';
|
|
8
9
|
import { getSizes, getTheme, getColorByToken, getDefaultObserveTarget } from './utils.js';
|
|
9
10
|
|
|
10
|
-
var
|
|
11
|
-
var elementPart = element ? "-".concat(element.toLowerCase()) : '';
|
|
12
|
-
return dataTestId ? "".concat(dataTestId).concat(elementPart) : undefined;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
var styles = {"component":"pattern-lock__component_1an4o","hidden":"pattern-lock__hidden_1an4o","error":"pattern-lock__error_1an4o","forgotBtn":"pattern-lock__forgotBtn_1an4o"};
|
|
11
|
+
var styles = {"component":"pattern-lock__component_1g0p7","hidden":"pattern-lock__hidden_1g0p7","error":"pattern-lock__error_1g0p7","forgotBtn":"pattern-lock__forgotBtn_1g0p7"};
|
|
16
12
|
require('./index.css')
|
|
17
13
|
|
|
18
14
|
var PatternLock = forwardRef(function (_a, ref) {
|
|
@@ -54,7 +50,7 @@ var PatternLock = forwardRef(function (_a, ref) {
|
|
|
54
50
|
React.createElement("div", { className: styles.error }, error),
|
|
55
51
|
React.createElement(Gap, { size: '3xl' }),
|
|
56
52
|
React.createElement(ReactCanvasPatternLock, __assign({}, restProps, params, { ref: ref, rows: 3, cols: 3, justifyNodes: justifyNodes, extraBounds: extraBounds })),
|
|
57
|
-
showForgotCodeBtn ? (React.createElement(
|
|
53
|
+
showForgotCodeBtn ? (React.createElement(ButtonMobile, { view: 'link', className: styles.forgotBtn, onClick: onForgotBtnClick, dataTestId: getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React.createElement("div", { className: styles.forgotBtn }))));
|
|
58
54
|
});
|
|
59
55
|
|
|
60
56
|
export { PatternLock };
|
package/esm/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: 13t3a */
|
|
2
2
|
:root {
|
|
3
3
|
} /* deprecated */ :root {
|
|
4
4
|
--color-light-text-negative: #d91d0b; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
--size-m-height: 56px;
|
|
27
27
|
} :root {
|
|
28
28
|
--pattern-lock-max-width: 500px;
|
|
29
|
-
} .pattern-
|
|
29
|
+
} .pattern-lock__component_1g0p7 {
|
|
30
30
|
max-width: var(--pattern-lock-max-width);
|
|
31
31
|
margin: var(--gap-xs) 0 var(--gap-xl) 0
|
|
32
|
-
} .pattern-
|
|
32
|
+
} .pattern-lock__component_1g0p7 canvas {
|
|
33
33
|
display: block;
|
|
34
34
|
margin: 0 auto;
|
|
35
|
-
} .pattern-
|
|
35
|
+
} .pattern-lock__hidden_1g0p7 {
|
|
36
36
|
visibility: hidden;
|
|
37
|
-
} .pattern-
|
|
37
|
+
} .pattern-lock__error_1g0p7 {
|
|
38
38
|
font-size: 16px;
|
|
39
39
|
line-height: 24px;
|
|
40
40
|
font-weight: 400;
|
|
@@ -45,25 +45,25 @@
|
|
|
45
45
|
padding: 0 var(--gap-m);
|
|
46
46
|
min-height: 24px;
|
|
47
47
|
color: var(--color-light-text-negative);
|
|
48
|
-
} .pattern-
|
|
48
|
+
} .pattern-lock__forgotBtn_1g0p7 {
|
|
49
49
|
display: block;
|
|
50
50
|
min-height: var(--size-xs-height);
|
|
51
51
|
margin: var(--gap-xl) auto 0;
|
|
52
52
|
} @media screen and (min-width: 360px) {
|
|
53
|
-
.pattern-
|
|
53
|
+
.pattern-lock__forgotBtn_1g0p7 {
|
|
54
54
|
margin-top: var(--gap-2xl);
|
|
55
55
|
min-height: var(--size-s-height);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
.pattern-
|
|
58
|
+
.pattern-lock__component_1g0p7 {
|
|
59
59
|
margin-bottom: var(--gap-s);
|
|
60
60
|
}
|
|
61
61
|
} @media screen and (min-width: 390px) {
|
|
62
|
-
.pattern-
|
|
62
|
+
.pattern-lock__forgotBtn_1g0p7 {
|
|
63
63
|
min-height: var(--size-m-height);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
.pattern-
|
|
66
|
+
.pattern-lock__component_1g0p7 {
|
|
67
67
|
margin-bottom: var(--gap-l);
|
|
68
68
|
}
|
|
69
69
|
}
|
package/esm/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import 'tslib';
|
|
|
4
4
|
import 'react';
|
|
5
5
|
import 'react-canvas-pattern-lock';
|
|
6
6
|
import 'classnames';
|
|
7
|
-
import '@alfalab/core-components-button/esm';
|
|
7
|
+
import '@alfalab/core-components-button/esm/mobile';
|
|
8
8
|
import '@alfalab/core-components-gap/esm';
|
|
9
|
+
import '@alfalab/core-components-shared/esm';
|
|
9
10
|
import './utils.js';
|
package/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: 13t3a */
|
|
2
2
|
:root {
|
|
3
3
|
} /* deprecated */ :root {
|
|
4
4
|
--color-light-text-negative: #d91d0b; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
--size-m-height: 56px;
|
|
27
27
|
} :root {
|
|
28
28
|
--pattern-lock-max-width: 500px;
|
|
29
|
-
} .pattern-
|
|
29
|
+
} .pattern-lock__component_1g0p7 {
|
|
30
30
|
max-width: var(--pattern-lock-max-width);
|
|
31
31
|
margin: var(--gap-xs) 0 var(--gap-xl) 0
|
|
32
|
-
} .pattern-
|
|
32
|
+
} .pattern-lock__component_1g0p7 canvas {
|
|
33
33
|
display: block;
|
|
34
34
|
margin: 0 auto;
|
|
35
|
-
} .pattern-
|
|
35
|
+
} .pattern-lock__hidden_1g0p7 {
|
|
36
36
|
visibility: hidden;
|
|
37
|
-
} .pattern-
|
|
37
|
+
} .pattern-lock__error_1g0p7 {
|
|
38
38
|
font-size: 16px;
|
|
39
39
|
line-height: 24px;
|
|
40
40
|
font-weight: 400;
|
|
@@ -45,25 +45,25 @@
|
|
|
45
45
|
padding: 0 var(--gap-m);
|
|
46
46
|
min-height: 24px;
|
|
47
47
|
color: var(--color-light-text-negative);
|
|
48
|
-
} .pattern-
|
|
48
|
+
} .pattern-lock__forgotBtn_1g0p7 {
|
|
49
49
|
display: block;
|
|
50
50
|
min-height: var(--size-xs-height);
|
|
51
51
|
margin: var(--gap-xl) auto 0;
|
|
52
52
|
} @media screen and (min-width: 360px) {
|
|
53
|
-
.pattern-
|
|
53
|
+
.pattern-lock__forgotBtn_1g0p7 {
|
|
54
54
|
margin-top: var(--gap-2xl);
|
|
55
55
|
min-height: var(--size-s-height);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
.pattern-
|
|
58
|
+
.pattern-lock__component_1g0p7 {
|
|
59
59
|
margin-bottom: var(--gap-s);
|
|
60
60
|
}
|
|
61
61
|
} @media screen and (min-width: 390px) {
|
|
62
|
-
.pattern-
|
|
62
|
+
.pattern-lock__forgotBtn_1g0p7 {
|
|
63
63
|
min-height: var(--size-m-height);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
.pattern-
|
|
66
|
+
.pattern-lock__component_1g0p7 {
|
|
67
67
|
margin-bottom: var(--gap-l);
|
|
68
68
|
}
|
|
69
69
|
}
|
package/index.js
CHANGED
|
@@ -8,8 +8,9 @@ require('tslib');
|
|
|
8
8
|
require('react');
|
|
9
9
|
require('react-canvas-pattern-lock');
|
|
10
10
|
require('classnames');
|
|
11
|
-
require('@alfalab/core-components-button');
|
|
11
|
+
require('@alfalab/core-components-button/mobile');
|
|
12
12
|
require('@alfalab/core-components-gap');
|
|
13
|
+
require('@alfalab/core-components-shared');
|
|
13
14
|
require('./utils.js');
|
|
14
15
|
|
|
15
16
|
|
package/modern/Component.js
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import React, { forwardRef, useState, useEffect } from 'react';
|
|
2
2
|
import { ReactCanvasPatternLock } from 'react-canvas-pattern-lock';
|
|
3
3
|
import cn from 'classnames';
|
|
4
|
-
import {
|
|
4
|
+
import { ButtonMobile } from '@alfalab/core-components-button/modern/mobile';
|
|
5
5
|
import { Gap } from '@alfalab/core-components-gap/modern';
|
|
6
|
+
import { getDataTestId } from '@alfalab/core-components-shared/modern';
|
|
6
7
|
import { THEME_STATE, DEFAULT_EXTRA_BOUNDS, OBSERVE_OPTIONS, OBSERVABLE_TOKENS } from './consts.js';
|
|
7
8
|
import { getSizes, getTheme, getColorByToken, getDefaultObserveTarget } from './utils.js';
|
|
8
9
|
|
|
9
|
-
const
|
|
10
|
-
const elementPart = element ? `-${element.toLowerCase()}` : '';
|
|
11
|
-
return dataTestId ? `${dataTestId}${elementPart}` : undefined;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const styles = {"component":"pattern-lock__component_1an4o","hidden":"pattern-lock__hidden_1an4o","error":"pattern-lock__error_1an4o","forgotBtn":"pattern-lock__forgotBtn_1an4o"};
|
|
10
|
+
const styles = {"component":"pattern-lock__component_1g0p7","hidden":"pattern-lock__hidden_1g0p7","error":"pattern-lock__error_1g0p7","forgotBtn":"pattern-lock__forgotBtn_1g0p7"};
|
|
15
11
|
require('./index.css')
|
|
16
12
|
|
|
17
13
|
const PatternLock = forwardRef(({ observeTokens = false, observerParams = {}, justifyNodes = 'space-between', className, error, dataTestId, forgotCodeBtnText = 'Забыли код?', showForgotCodeBtn = false, onForgotBtnClick, extraBounds = DEFAULT_EXTRA_BOUNDS, ...restProps }, ref) => {
|
|
@@ -49,7 +45,7 @@ const PatternLock = forwardRef(({ observeTokens = false, observerParams = {}, ju
|
|
|
49
45
|
React.createElement("div", { className: styles.error }, error),
|
|
50
46
|
React.createElement(Gap, { size: '3xl' }),
|
|
51
47
|
React.createElement(ReactCanvasPatternLock, { ...restProps, ...params, ref: ref, rows: 3, cols: 3, justifyNodes: justifyNodes, extraBounds: extraBounds }),
|
|
52
|
-
showForgotCodeBtn ? (React.createElement(
|
|
48
|
+
showForgotCodeBtn ? (React.createElement(ButtonMobile, { view: 'link', className: styles.forgotBtn, onClick: onForgotBtnClick, dataTestId: getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React.createElement("div", { className: styles.forgotBtn }))));
|
|
53
49
|
});
|
|
54
50
|
|
|
55
51
|
export { PatternLock };
|
package/modern/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: 13t3a */
|
|
2
2
|
:root {
|
|
3
3
|
} /* deprecated */ :root {
|
|
4
4
|
--color-light-text-negative: #d91d0b; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
--size-m-height: 56px;
|
|
27
27
|
} :root {
|
|
28
28
|
--pattern-lock-max-width: 500px;
|
|
29
|
-
} .pattern-
|
|
29
|
+
} .pattern-lock__component_1g0p7 {
|
|
30
30
|
max-width: var(--pattern-lock-max-width);
|
|
31
31
|
margin: var(--gap-xs) 0 var(--gap-xl) 0
|
|
32
|
-
} .pattern-
|
|
32
|
+
} .pattern-lock__component_1g0p7 canvas {
|
|
33
33
|
display: block;
|
|
34
34
|
margin: 0 auto;
|
|
35
|
-
} .pattern-
|
|
35
|
+
} .pattern-lock__hidden_1g0p7 {
|
|
36
36
|
visibility: hidden;
|
|
37
|
-
} .pattern-
|
|
37
|
+
} .pattern-lock__error_1g0p7 {
|
|
38
38
|
font-size: 16px;
|
|
39
39
|
line-height: 24px;
|
|
40
40
|
font-weight: 400;
|
|
@@ -45,25 +45,25 @@
|
|
|
45
45
|
padding: 0 var(--gap-m);
|
|
46
46
|
min-height: 24px;
|
|
47
47
|
color: var(--color-light-text-negative);
|
|
48
|
-
} .pattern-
|
|
48
|
+
} .pattern-lock__forgotBtn_1g0p7 {
|
|
49
49
|
display: block;
|
|
50
50
|
min-height: var(--size-xs-height);
|
|
51
51
|
margin: var(--gap-xl) auto 0;
|
|
52
52
|
} @media screen and (min-width: 360px) {
|
|
53
|
-
.pattern-
|
|
53
|
+
.pattern-lock__forgotBtn_1g0p7 {
|
|
54
54
|
margin-top: var(--gap-2xl);
|
|
55
55
|
min-height: var(--size-s-height);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
.pattern-
|
|
58
|
+
.pattern-lock__component_1g0p7 {
|
|
59
59
|
margin-bottom: var(--gap-s);
|
|
60
60
|
}
|
|
61
61
|
} @media screen and (min-width: 390px) {
|
|
62
|
-
.pattern-
|
|
62
|
+
.pattern-lock__forgotBtn_1g0p7 {
|
|
63
63
|
min-height: var(--size-m-height);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
.pattern-
|
|
66
|
+
.pattern-lock__component_1g0p7 {
|
|
67
67
|
margin-bottom: var(--gap-l);
|
|
68
68
|
}
|
|
69
69
|
}
|
package/modern/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { THEME_STATE } from './consts.js';
|
|
|
3
3
|
import 'react';
|
|
4
4
|
import 'react-canvas-pattern-lock';
|
|
5
5
|
import 'classnames';
|
|
6
|
-
import '@alfalab/core-components-button/modern';
|
|
6
|
+
import '@alfalab/core-components-button/modern/mobile';
|
|
7
7
|
import '@alfalab/core-components-gap/modern';
|
|
8
|
+
import '@alfalab/core-components-shared/modern';
|
|
8
9
|
import './utils.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfalab/core-components-pattern-lock",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Pattern lock",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
"react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@alfalab/core-components-button": "^
|
|
19
|
-
"@alfalab/core-components-gap": "^1.
|
|
18
|
+
"@alfalab/core-components-button": "^9.0.0",
|
|
19
|
+
"@alfalab/core-components-gap": "^1.2.0",
|
|
20
|
+
"@alfalab/core-components-shared": "^0.1.0",
|
|
20
21
|
"react-canvas-pattern-lock": "^1.1.1",
|
|
21
22
|
"classnames": "^2.3.1",
|
|
22
23
|
"tslib": "^2.4.0"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React, { forwardRef, useEffect, useState } from 'react';
|
|
2
|
+
import type { Theme, TPatternLockInstance } from 'react-canvas-pattern-lock';
|
|
3
|
+
import { ReactCanvasPatternLock } from 'react-canvas-pattern-lock';
|
|
4
|
+
import cn from 'classnames';
|
|
5
|
+
|
|
6
|
+
import { ButtonMobile } from '@alfalab/core-components-button/mobile';
|
|
7
|
+
import { Gap } from '@alfalab/core-components-gap';
|
|
8
|
+
import { getDataTestId } from '@alfalab/core-components-shared';
|
|
9
|
+
|
|
10
|
+
import { DEFAULT_EXTRA_BOUNDS, OBSERVABLE_TOKENS, OBSERVE_OPTIONS, THEME_STATE } from './consts';
|
|
11
|
+
import type { PatternLockProps } from './typings';
|
|
12
|
+
import { getColorByToken, getDefaultObserveTarget, getSizes, getTheme } from './utils';
|
|
13
|
+
|
|
14
|
+
import styles from './index.module.css';
|
|
15
|
+
|
|
16
|
+
export const PatternLock = forwardRef<TPatternLockInstance, PatternLockProps>(
|
|
17
|
+
(
|
|
18
|
+
{
|
|
19
|
+
observeTokens = false,
|
|
20
|
+
observerParams = {},
|
|
21
|
+
justifyNodes = 'space-between',
|
|
22
|
+
className,
|
|
23
|
+
error,
|
|
24
|
+
dataTestId,
|
|
25
|
+
forgotCodeBtnText = 'Забыли код?',
|
|
26
|
+
showForgotCodeBtn = false,
|
|
27
|
+
onForgotBtnClick,
|
|
28
|
+
extraBounds = DEFAULT_EXTRA_BOUNDS,
|
|
29
|
+
...restProps
|
|
30
|
+
},
|
|
31
|
+
ref,
|
|
32
|
+
) => {
|
|
33
|
+
const [params, setParams] = useState<
|
|
34
|
+
{ theme: Theme; width: number; height: number } | undefined
|
|
35
|
+
>();
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const { elementSizes, width, height } = getSizes();
|
|
39
|
+
|
|
40
|
+
setParams({
|
|
41
|
+
theme: getTheme(elementSizes),
|
|
42
|
+
width,
|
|
43
|
+
height,
|
|
44
|
+
});
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
let styleObserver: MutationObserver | null = null;
|
|
49
|
+
|
|
50
|
+
if (observeTokens) {
|
|
51
|
+
const { options = OBSERVE_OPTIONS, getTarget = getDefaultObserveTarget } =
|
|
52
|
+
observerParams;
|
|
53
|
+
|
|
54
|
+
styleObserver = new MutationObserver(() =>
|
|
55
|
+
setParams((prevState) => {
|
|
56
|
+
const { width, height, elementSizes } = getSizes();
|
|
57
|
+
|
|
58
|
+
if (!prevState) {
|
|
59
|
+
return { theme: getTheme(elementSizes), width, height };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const prevBgColor = prevState.theme[THEME_STATE.INITIAL].colors.bg;
|
|
63
|
+
const themeChanged = prevBgColor !== getColorByToken(OBSERVABLE_TOKENS.BG);
|
|
64
|
+
|
|
65
|
+
if (themeChanged) return { ...prevState, theme: getTheme(elementSizes) };
|
|
66
|
+
|
|
67
|
+
return prevState;
|
|
68
|
+
}),
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
styleObserver.observe(getTarget(), options);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return () => styleObserver?.disconnect();
|
|
75
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
|
+
}, [observeTokens]);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
className={cn(styles.component, className, { [styles.hidden]: !params })}
|
|
81
|
+
data-test-id={dataTestId}
|
|
82
|
+
>
|
|
83
|
+
<Gap size='xs' />
|
|
84
|
+
|
|
85
|
+
<div className={styles.error}>{error}</div>
|
|
86
|
+
|
|
87
|
+
<Gap size='3xl' />
|
|
88
|
+
|
|
89
|
+
<ReactCanvasPatternLock
|
|
90
|
+
{...restProps}
|
|
91
|
+
{...params}
|
|
92
|
+
ref={ref}
|
|
93
|
+
rows={3}
|
|
94
|
+
cols={3}
|
|
95
|
+
justifyNodes={justifyNodes}
|
|
96
|
+
extraBounds={extraBounds}
|
|
97
|
+
/>
|
|
98
|
+
|
|
99
|
+
{showForgotCodeBtn ? (
|
|
100
|
+
<ButtonMobile
|
|
101
|
+
view='link'
|
|
102
|
+
className={styles.forgotBtn}
|
|
103
|
+
onClick={onForgotBtnClick}
|
|
104
|
+
dataTestId={getDataTestId(dataTestId, 'forgot-code-btn')}
|
|
105
|
+
>
|
|
106
|
+
{forgotCodeBtnText}
|
|
107
|
+
</ButtonMobile>
|
|
108
|
+
) : (
|
|
109
|
+
<div className={styles.forgotBtn} />
|
|
110
|
+
)}
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
},
|
|
114
|
+
);
|
package/src/consts.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ReactPatternLockProps } from 'react-canvas-pattern-lock';
|
|
2
|
+
|
|
3
|
+
import type { ObservableTokens } from './typings';
|
|
4
|
+
|
|
5
|
+
export const OBSERVE_OPTIONS: MutationObserverInit = {
|
|
6
|
+
childList: true,
|
|
7
|
+
attributes: false,
|
|
8
|
+
characterData: false,
|
|
9
|
+
subtree: true,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const DEFAULT_EXTRA_BOUNDS: ReactPatternLockProps['extraBounds'] = [75, 50, 75, 50];
|
|
13
|
+
|
|
14
|
+
export const OBSERVABLE_TOKENS: ObservableTokens = {
|
|
15
|
+
ACCENT_INITIAL: '--color-light-graphic-primary',
|
|
16
|
+
ACCENT_SUCCESS: '--color-light-graphic-positive',
|
|
17
|
+
ACCENT_FAILURE: '--color-light-graphic-negative',
|
|
18
|
+
PRIMARY: '--color-light-graphic-tertiary',
|
|
19
|
+
BG: '--color-light-bg-primary',
|
|
20
|
+
RING_BG_INITIAL: '--color-light-specialbg-secondary-transparent',
|
|
21
|
+
SELECTED_RING_BG_INITIAL: '--color-light-specialbg-tertiary-transparent',
|
|
22
|
+
SELECTED_RING_BG_SUCCESS: '--color-light-graphic-positive-alpha-10',
|
|
23
|
+
SELECTED_RING_BG_FAILURE: '--color-light-graphic-negative-alpha-10',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const THEME_STATE = {
|
|
27
|
+
INITIAL: 'initial',
|
|
28
|
+
SUCCESS: 'success',
|
|
29
|
+
FAILURE: 'failure',
|
|
30
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
@import '@alfalab/core-components-themes/src/default.css';
|
|
2
|
+
@import './vars.css';
|
|
3
|
+
|
|
4
|
+
.component {
|
|
5
|
+
max-width: var(--pattern-lock-max-width);
|
|
6
|
+
margin: var(--gap-xs) 0 var(--gap-xl) 0;
|
|
7
|
+
|
|
8
|
+
& canvas {
|
|
9
|
+
display: block;
|
|
10
|
+
margin: 0 auto;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.hidden {
|
|
15
|
+
visibility: hidden;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.error {
|
|
19
|
+
@mixin paragraph_primary_medium;
|
|
20
|
+
|
|
21
|
+
display: flex;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
align-items: center;
|
|
24
|
+
padding: 0 var(--gap-m);
|
|
25
|
+
min-height: 24px;
|
|
26
|
+
color: var(--color-light-text-negative);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.forgotBtn {
|
|
30
|
+
display: block;
|
|
31
|
+
min-height: var(--size-xs-height);
|
|
32
|
+
margin: var(--gap-xl) auto 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media screen and (min-width: 360px) {
|
|
36
|
+
.forgotBtn {
|
|
37
|
+
margin-top: var(--gap-2xl);
|
|
38
|
+
min-height: var(--size-s-height);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.component {
|
|
42
|
+
margin-bottom: var(--gap-s);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@media screen and (min-width: 390px) {
|
|
47
|
+
.forgotBtn {
|
|
48
|
+
min-height: var(--size-m-height);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.component {
|
|
52
|
+
margin-bottom: var(--gap-l);
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/index.ts
ADDED
package/src/typings.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MouseEvent, ReactNode } from 'react';
|
|
2
|
+
import { ReactPatternLockProps } from 'react-canvas-pattern-lock';
|
|
3
|
+
|
|
4
|
+
type ConditionalProps =
|
|
5
|
+
| {
|
|
6
|
+
/**
|
|
7
|
+
* Текст кнопки "забыли код"
|
|
8
|
+
* @default "Забыли код?"
|
|
9
|
+
*/
|
|
10
|
+
showForgotCodeBtn: true;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Текст кнопки "забыли код"
|
|
14
|
+
* @default "Забыли код?"
|
|
15
|
+
*/
|
|
16
|
+
forgotCodeBtnText?: string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Коллбэк, вызываемый при клике на кнопку "Забыли код"
|
|
20
|
+
*/
|
|
21
|
+
onForgotBtnClick: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
22
|
+
}
|
|
23
|
+
| {
|
|
24
|
+
showForgotCodeBtn?: false;
|
|
25
|
+
onForgotBtnClick?: never;
|
|
26
|
+
forgotCodeBtnText?: never;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type PatternLockProps = {
|
|
30
|
+
/**
|
|
31
|
+
* Дополнительный класс.
|
|
32
|
+
*/
|
|
33
|
+
className?: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Сообщение об ошибке
|
|
37
|
+
*/
|
|
38
|
+
error?: ReactNode;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Идентификатор для систем автоматизированного тестирования.
|
|
42
|
+
*/
|
|
43
|
+
dataTestId?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Следить ли за изменениями значений цветовых токенов.
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
49
|
+
observeTokens?: boolean;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Параметры MutationObserver для наблюдения за изменениями режима(css custom properties).
|
|
53
|
+
*/
|
|
54
|
+
observerParams?: {
|
|
55
|
+
getTarget?: () => Node;
|
|
56
|
+
options?: MutationObserverInit;
|
|
57
|
+
};
|
|
58
|
+
} & Omit<ReactPatternLockProps, 'theme' | 'width' | 'height' | 'rows' | 'cols'> &
|
|
59
|
+
ConditionalProps;
|
|
60
|
+
|
|
61
|
+
export type ObservableTokens = {
|
|
62
|
+
ACCENT_INITIAL: string;
|
|
63
|
+
ACCENT_SUCCESS: string;
|
|
64
|
+
ACCENT_FAILURE: string;
|
|
65
|
+
RING_BG_INITIAL: string;
|
|
66
|
+
SELECTED_RING_BG_INITIAL: string;
|
|
67
|
+
SELECTED_RING_BG_SUCCESS: string;
|
|
68
|
+
SELECTED_RING_BG_FAILURE: string;
|
|
69
|
+
PRIMARY: string;
|
|
70
|
+
BG: string;
|
|
71
|
+
};
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Theme, ThemeParams } from 'react-canvas-pattern-lock';
|
|
2
|
+
|
|
3
|
+
import { OBSERVABLE_TOKENS, THEME_STATE } from './consts';
|
|
4
|
+
|
|
5
|
+
export function getDefaultObserveTarget() {
|
|
6
|
+
return document.head;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getColorByToken(token: string) {
|
|
10
|
+
return getComputedStyle(document.documentElement).getPropertyValue(token);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const getSizes = (() => {
|
|
14
|
+
const COMMON_SIZES = {
|
|
15
|
+
lineWidth: 6,
|
|
16
|
+
nodeRing: 0,
|
|
17
|
+
nodeCore: 12,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
let cachedSize: { elementSizes: ThemeParams['dimens']; width: number; height: number };
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
if (cachedSize) {
|
|
24
|
+
return cachedSize;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (window.matchMedia('(min-width: 390px)').matches) {
|
|
28
|
+
cachedSize = {
|
|
29
|
+
elementSizes: { ...COMMON_SIZES, nodeRadius: 43 },
|
|
30
|
+
width: 322,
|
|
31
|
+
height: 322,
|
|
32
|
+
};
|
|
33
|
+
} else if (window.matchMedia('(min-width: 360px)').matches) {
|
|
34
|
+
cachedSize = {
|
|
35
|
+
elementSizes: { ...COMMON_SIZES, nodeRadius: 38 },
|
|
36
|
+
width: 292,
|
|
37
|
+
height: 292,
|
|
38
|
+
};
|
|
39
|
+
} else {
|
|
40
|
+
cachedSize = {
|
|
41
|
+
elementSizes: { ...COMMON_SIZES, nodeRadius: 32 },
|
|
42
|
+
width: 240,
|
|
43
|
+
height: 240,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return cachedSize;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
|
|
51
|
+
export function getTheme(dimens: ThemeParams['dimens']): Theme {
|
|
52
|
+
const baseColors = {
|
|
53
|
+
primary: getColorByToken(OBSERVABLE_TOKENS.PRIMARY),
|
|
54
|
+
bg: getColorByToken(OBSERVABLE_TOKENS.BG),
|
|
55
|
+
ringBg: getColorByToken(OBSERVABLE_TOKENS.RING_BG_INITIAL),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
[THEME_STATE.INITIAL]: {
|
|
60
|
+
colors: {
|
|
61
|
+
...baseColors,
|
|
62
|
+
accent: getColorByToken(OBSERVABLE_TOKENS.ACCENT_INITIAL),
|
|
63
|
+
selectedRingBg: getColorByToken(OBSERVABLE_TOKENS.SELECTED_RING_BG_INITIAL),
|
|
64
|
+
},
|
|
65
|
+
dimens,
|
|
66
|
+
},
|
|
67
|
+
[THEME_STATE.SUCCESS]: {
|
|
68
|
+
colors: {
|
|
69
|
+
...baseColors,
|
|
70
|
+
accent: getColorByToken(OBSERVABLE_TOKENS.ACCENT_SUCCESS),
|
|
71
|
+
selectedRingBg: getColorByToken(OBSERVABLE_TOKENS.SELECTED_RING_BG_SUCCESS),
|
|
72
|
+
},
|
|
73
|
+
dimens,
|
|
74
|
+
},
|
|
75
|
+
[THEME_STATE.FAILURE]: {
|
|
76
|
+
colors: {
|
|
77
|
+
...baseColors,
|
|
78
|
+
accent: getColorByToken(OBSERVABLE_TOKENS.ACCENT_FAILURE),
|
|
79
|
+
selectedRingBg: getColorByToken(OBSERVABLE_TOKENS.SELECTED_RING_BG_FAILURE),
|
|
80
|
+
},
|
|
81
|
+
dimens,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
package/src/vars.css
ADDED