@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 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 coreComponentsButton = require('@alfalab/core-components-button');
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 getDataTestId = function (dataTestId, element) {
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(coreComponentsButton.Button, { view: 'link', className: styles.forgotBtn, onClick: onForgotBtnClick, dataTestId: getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React__default.default.createElement("div", { className: styles.forgotBtn }))));
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 coreComponentsButton = require('@alfalab/core-components-button/cssm');
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(coreComponentsButton.Button, { view: 'link', className: styles__default.default.forgotBtn, onClick: onForgotBtnClick, dataTestId: getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React__default.default.createElement("div", { className: styles__default.default.forgotBtn }))));
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 { Button } from '@alfalab/core-components-button/esm';
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 getDataTestId = function (dataTestId, element) {
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(Button, { view: 'link', className: styles.forgotBtn, onClick: onForgotBtnClick, dataTestId: getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React.createElement("div", { className: styles.forgotBtn }))));
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: yvl29 */
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-lock__component_1an4o {
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-lock__component_1an4o canvas {
32
+ } .pattern-lock__component_1g0p7 canvas {
33
33
  display: block;
34
34
  margin: 0 auto;
35
- } .pattern-lock__hidden_1an4o {
35
+ } .pattern-lock__hidden_1g0p7 {
36
36
  visibility: hidden;
37
- } .pattern-lock__error_1an4o {
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-lock__forgotBtn_1an4o {
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-lock__forgotBtn_1an4o {
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-lock__component_1an4o {
58
+ .pattern-lock__component_1g0p7 {
59
59
  margin-bottom: var(--gap-s);
60
60
  }
61
61
  } @media screen and (min-width: 390px) {
62
- .pattern-lock__forgotBtn_1an4o {
62
+ .pattern-lock__forgotBtn_1g0p7 {
63
63
  min-height: var(--size-m-height);
64
64
  }
65
65
 
66
- .pattern-lock__component_1an4o {
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: yvl29 */
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-lock__component_1an4o {
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-lock__component_1an4o canvas {
32
+ } .pattern-lock__component_1g0p7 canvas {
33
33
  display: block;
34
34
  margin: 0 auto;
35
- } .pattern-lock__hidden_1an4o {
35
+ } .pattern-lock__hidden_1g0p7 {
36
36
  visibility: hidden;
37
- } .pattern-lock__error_1an4o {
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-lock__forgotBtn_1an4o {
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-lock__forgotBtn_1an4o {
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-lock__component_1an4o {
58
+ .pattern-lock__component_1g0p7 {
59
59
  margin-bottom: var(--gap-s);
60
60
  }
61
61
  } @media screen and (min-width: 390px) {
62
- .pattern-lock__forgotBtn_1an4o {
62
+ .pattern-lock__forgotBtn_1g0p7 {
63
63
  min-height: var(--size-m-height);
64
64
  }
65
65
 
66
- .pattern-lock__component_1an4o {
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
 
@@ -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 { Button } from '@alfalab/core-components-button/modern';
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 getDataTestId = (dataTestId, element) => {
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(Button, { view: 'link', className: styles.forgotBtn, onClick: onForgotBtnClick, dataTestId: getDataTestId(dataTestId, 'forgot-code-btn') }, forgotCodeBtnText)) : (React.createElement("div", { className: styles.forgotBtn }))));
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: yvl29 */
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-lock__component_1an4o {
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-lock__component_1an4o canvas {
32
+ } .pattern-lock__component_1g0p7 canvas {
33
33
  display: block;
34
34
  margin: 0 auto;
35
- } .pattern-lock__hidden_1an4o {
35
+ } .pattern-lock__hidden_1g0p7 {
36
36
  visibility: hidden;
37
- } .pattern-lock__error_1an4o {
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-lock__forgotBtn_1an4o {
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-lock__forgotBtn_1an4o {
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-lock__component_1an4o {
58
+ .pattern-lock__component_1g0p7 {
59
59
  margin-bottom: var(--gap-s);
60
60
  }
61
61
  } @media screen and (min-width: 390px) {
62
- .pattern-lock__forgotBtn_1an4o {
62
+ .pattern-lock__forgotBtn_1g0p7 {
63
63
  min-height: var(--size-m-height);
64
64
  }
65
65
 
66
- .pattern-lock__component_1an4o {
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.2.4",
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": "^8.5.1",
19
- "@alfalab/core-components-gap": "^1.1.3",
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
@@ -0,0 +1,3 @@
1
+ export type { PatternLockProps } from './typings';
2
+ export * from './Component';
3
+ export { THEME_STATE } from './consts';
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
@@ -0,0 +1,3 @@
1
+ :root {
2
+ --pattern-lock-max-width: 500px;
3
+ }