Skip to content

Commit 11bc640

Browse files
authored
feat(newPassword): new view input password (#119)
1 parent 777d17e commit 11bc640

File tree

12 files changed

+121
-76
lines changed

12 files changed

+121
-76
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
export const OBJECT_ARRAY_FLAG = '____arr-obj';
22

33
export const OBJECT_ARRAY_CNT = '____arr-obj-cnt';
4+
5+
export const SPEC_TYPE_FOR_GENERATE_BUTTON = ['base', 'password', 'textarea'];

src/lib/core/components/Form/utils/common.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import _ from 'lodash';
22

33
import {SpecTypes} from '../../../constants';
4-
import {FormValue, ObjectValue} from '../../../types';
5-
import {OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG} from '../constants';
4+
import {isStringSpec} from '../../../helpers';
5+
import {FormValue, ObjectValue, Spec} from '../../../types';
6+
import {OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG, SPEC_TYPE_FOR_GENERATE_BUTTON} from '../constants';
67

78
export const isCorrectConfig = (candidate: any) =>
89
Object.values(SpecTypes).every(
@@ -68,3 +69,8 @@ export const transformArrOut = <Type extends FormValue, ReturnType extends FormV
6869
};
6970

7071
export const isArrayItem = (name: string) => name[name.length - 1] === '>';
72+
73+
export const withGenerateButton = (spec: Spec) =>
74+
isStringSpec(spec) &&
75+
SPEC_TYPE_FOR_GENERATE_BUTTON.includes(spec.viewSpec.type) &&
76+
spec.viewSpec.generateRandomValueButton;

src/lib/kit/components/ErrorWrapper/ErrorWrapper.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ export interface ErrorWrapperProps {
1212
name: string;
1313
meta: FieldRenderProps<FieldValue>['meta'];
1414
withoutChildErrorStyles?: boolean;
15+
className?: string;
1516
}
1617

1718
export const ErrorWrapper: React.FC<ErrorWrapperProps> = ({
1819
name,
1920
meta,
2021
withoutChildErrorStyles,
2122
children,
23+
className,
2224
}) => {
2325
const error = React.useMemo(() => {
2426
if ((meta.touched || meta.submitFailed) && meta.error) {
@@ -34,7 +36,10 @@ export const ErrorWrapper: React.FC<ErrorWrapperProps> = ({
3436
);
3537

3638
return (
37-
<span className={b({error: !withoutChildErrorStyles && Boolean(error)})} {...props}>
39+
<span
40+
className={b({error: !withoutChildErrorStyles && Boolean(error)}, className)}
41+
{...props}
42+
>
3843
{children}
3944
{error && typeof error === 'string' ? (
4045
<div className={b('error-text')}>{error}</div>

src/lib/kit/components/Inputs/Text/Text.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@
22

33
.#{$ns}text {
44
display: flex;
5+
6+
&__button {
7+
--yc-button-background-color-hover: transparent;
8+
}
59
}
Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import React from 'react';
22

3-
import {TextInput} from '@gravity-ui/uikit';
3+
import {Copy, CopyCheck, Eye, EyeSlash} from '@gravity-ui/icons';
4+
import {Button, CopyToClipboard, CopyToClipboardStatus, Icon, TextInput} from '@gravity-ui/uikit';
45
import _ from 'lodash';
56

6-
import {FieldRenderProps, NumberInputProps, StringInputProps, isStringSpec} from '../../../../core';
7+
import {FieldRenderProps, NumberInputProps, StringInputProps} from '../../../../core';
78
import {block} from '../../../utils';
8-
import {GenerateRandomValueButton} from '../../GenerateRandomValueButton';
99

1010
import './Text.scss';
1111

1212
const b = block('text');
1313

1414
export const Text = <T extends NumberInputProps | StringInputProps>({name, input, spec}: T) => {
1515
const {value, onBlur, onChange, onFocus} = input;
16+
const [hideValue, setHideValue] = React.useState(spec.viewSpec.type === 'password');
1617

1718
const handleChange = React.useCallback(
1819
(value: string) => {
@@ -29,45 +30,58 @@ export const Text = <T extends NumberInputProps | StringInputProps>({name, input
2930
return 'text';
3031
}, [spec.viewSpec.type]);
3132

32-
const textInput = React.useMemo(
33-
() => (
34-
<TextInput
35-
type={type}
36-
value={_.isNil(value) ? '' : `${value}`}
37-
hasClear={true}
38-
onBlur={onBlur}
39-
onFocus={onFocus}
40-
onUpdate={handleChange}
41-
disabled={spec.viewSpec.disabled}
42-
placeholder={spec.viewSpec.placeholder}
43-
autoComplete={type === 'password' ? 'new-password' : undefined}
44-
qa={name}
45-
/>
46-
),
47-
[
48-
handleChange,
49-
name,
50-
onBlur,
51-
onFocus,
52-
spec.viewSpec.disabled,
53-
spec.viewSpec.placeholder,
54-
type,
55-
value,
56-
],
57-
);
33+
const additionalRightContent = React.useMemo(() => {
34+
if (type === 'password') {
35+
const onClick = () => {
36+
setHideValue((hideValue) => !hideValue);
37+
};
5838

59-
const content = React.useMemo(() => {
60-
if (isStringSpec(spec)) {
6139
return (
6240
<div className={b()}>
63-
{textInput}
64-
<GenerateRandomValueButton spec={spec} onChange={handleChange} />
41+
{input.value ? (
42+
<CopyToClipboard text={String(value)} timeout={500}>
43+
{(state) => (
44+
<Button view="flat-secondary" className={b('button')} size="s">
45+
<Icon
46+
size={14}
47+
data={
48+
state === CopyToClipboardStatus.Pending
49+
? Copy
50+
: CopyCheck
51+
}
52+
/>
53+
</Button>
54+
)}
55+
</CopyToClipboard>
56+
) : null}
57+
<Button
58+
view="flat-secondary"
59+
onClick={onClick}
60+
className={b('button')}
61+
size="s"
62+
>
63+
<Icon data={hideValue ? Eye : EyeSlash} size={14} />
64+
</Button>
6565
</div>
6666
);
6767
}
6868

69-
return <React.Fragment>{textInput}</React.Fragment>;
70-
}, [handleChange, spec, textInput]);
69+
return undefined;
70+
}, [hideValue, input.value, type, value]);
7171

72-
return <React.Fragment>{content}</React.Fragment>;
72+
return (
73+
<TextInput
74+
type={hideValue ? 'password' : 'text'}
75+
value={_.isNil(value) ? '' : `${value}`}
76+
hasClear={true}
77+
onBlur={onBlur}
78+
onFocus={onFocus}
79+
onUpdate={handleChange}
80+
disabled={spec.viewSpec.disabled}
81+
placeholder={spec.viewSpec.placeholder}
82+
autoComplete={type === 'password' ? 'new-password' : undefined}
83+
qa={name}
84+
rightContent={additionalRightContent}
85+
/>
86+
);
7387
};

src/lib/kit/components/Inputs/TextArea/TextArea.scss

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/lib/kit/components/Inputs/TextArea/TextArea.tsx

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,22 @@ import React from 'react';
33
import {TextArea as TextAreaBase} from '@gravity-ui/uikit';
44

55
import {StringInput} from '../../../../core';
6-
import {block} from '../../../utils';
7-
import {GenerateRandomValueButton} from '../../GenerateRandomValueButton';
8-
9-
import './TextArea.scss';
10-
11-
const b = block('text-area');
126

137
export const TextArea: StringInput = ({name, input, spec}) => {
148
const {value, onBlur, onChange, onFocus} = input;
159

1610
return (
17-
<div className={b()}>
18-
<TextAreaBase
19-
value={value}
20-
onBlur={onBlur}
21-
onFocus={onFocus}
22-
onUpdate={onChange}
23-
maxRows={20}
24-
minRows={8}
25-
hasClear
26-
disabled={spec.viewSpec.disabled}
27-
placeholder={spec.viewSpec.placeholder}
28-
qa={name}
29-
/>
30-
<GenerateRandomValueButton spec={spec} onChange={onChange} />
31-
</div>
11+
<TextAreaBase
12+
value={value}
13+
onBlur={onBlur}
14+
onFocus={onFocus}
15+
onUpdate={onChange}
16+
maxRows={20}
17+
minRows={8}
18+
hasClear
19+
disabled={spec.viewSpec.disabled}
20+
placeholder={spec.viewSpec.placeholder}
21+
qa={name}
22+
/>
3223
);
3324
};

src/lib/kit/components/Layouts/Row/Row.scss

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010
margin-bottom: 0;
1111
}
1212

13-
&_extra-width {
14-
width: 533px;
15-
max-width: 533px;
16-
}
17-
1813
&__left {
1914
width: 180px;
2015
min-height: 28px;
@@ -90,4 +85,8 @@
9085
&__required-mark {
9186
color: var(--yc-color-text-danger);
9287
}
88+
89+
&__error-wrapper {
90+
min-width: 100%;
91+
}
9392
}

src/lib/kit/components/Layouts/Row/Row.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ import React from 'react';
33
import {HelpPopover} from '@gravity-ui/components';
44
import {TrashBin} from '@gravity-ui/icons';
55
import {Button, Icon} from '@gravity-ui/uikit';
6+
import _ from 'lodash';
67

78
import {
89
FieldValue,
910
LayoutProps,
1011
Spec,
12+
StringSpec,
1113
isArrayItem,
1214
isArraySpec,
1315
isObjectSpec,
16+
withGenerateButton,
1417
} from '../../../../core';
15-
import {ErrorWrapper} from '../../../components';
18+
import {ErrorWrapper, GenerateRandomValueButton} from '../../../components';
1619
import {block} from '../../../utils';
1720

1821
import './Row.scss';
@@ -32,9 +35,10 @@ const RowBase = <T extends FieldValue, S extends Spec>({
3235
children,
3336
}: LayoutProps<T, S> & RowProps) => {
3437
const arrayItem = React.useMemo(() => isArrayItem(name), [name]);
38+
const generateButton = React.useMemo(() => withGenerateButton(spec), [spec]);
3539

3640
return (
37-
<div className={b({'extra-width': isArraySpec(spec) || arrayItem})}>
41+
<div className={b()}>
3842
<div className={b('left')}>
3943
<div className={b('left-inner')}>
4044
<span className={b('title', {required: spec.required})}>
@@ -58,9 +62,16 @@ const RowBase = <T extends FieldValue, S extends Spec>({
5862
name={name}
5963
meta={meta}
6064
withoutChildErrorStyles={isArraySpec(spec) || isObjectSpec(spec)}
65+
className={b('error-wrapper')}
6166
>
6267
{children}
6368
</ErrorWrapper>
69+
{generateButton ? (
70+
<GenerateRandomValueButton
71+
spec={spec as StringSpec}
72+
onChange={input.onChange as (value: string) => void}
73+
/>
74+
) : null}
6475
{arrayItem ? (
6576
<Button
6677
view="flat-secondary"

src/lib/kit/components/Layouts/Row2/Row2.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import {
77
FieldValue,
88
LayoutProps,
99
Spec,
10+
StringSpec,
1011
isArrayItem,
1112
isArraySpec,
1213
isObjectSpec,
14+
withGenerateButton,
1315
} from '../../../../core';
14-
import {ErrorWrapper} from '../../../components';
16+
import {ErrorWrapper, GenerateRandomValueButton} from '../../../components';
1517
import {block} from '../../../utils';
1618

1719
import './Row2.scss';
@@ -25,6 +27,8 @@ export const Row2 = <T extends FieldValue, S extends Spec>({
2527
meta,
2628
children,
2729
}: LayoutProps<T, S>) => {
30+
const generateButton = React.useMemo(() => withGenerateButton(spec), [spec]);
31+
2832
return (
2933
<div className={b()}>
3034
<div className={b('left')}>
@@ -42,6 +46,12 @@ export const Row2 = <T extends FieldValue, S extends Spec>({
4246
>
4347
{children}
4448
</ErrorWrapper>
49+
{generateButton ? (
50+
<GenerateRandomValueButton
51+
spec={spec as StringSpec}
52+
onChange={input.onChange as (value: string) => void}
53+
/>
54+
) : null}
4555
{isArrayItem(name) ? (
4656
<Button
4757
view="flat-secondary"

0 commit comments

Comments
 (0)