@salutejs/sdds-api-tests 0.2.0-canary.2420.23801489438.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/LICENSE.txt +21 -0
- package/package.json +38 -0
- package/script.mjs +109 -0
- package/src/components/Button/Button.api.test.tsx +88 -0
- package/src/components/Checkbox/Checkbox.api.test.tsx +103 -0
- package/src/components/Combobox/Combobox.api.test.tsx +468 -0
- package/src/components/TextField/TextField.api.test.tsx +283 -0
- package/tsconfig.json +40 -0
- package/vitest.config.ts +12 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Salute Devices
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@salutejs/sdds-api-tests",
|
|
3
|
+
"version": "0.2.0-canary.2420.23801489438.0",
|
|
4
|
+
"description": "API tests for components",
|
|
5
|
+
"author": "Salute Frontend Team <salute.developers@gmail.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "ssh://git@github.com:salute-developers/plasma.git",
|
|
10
|
+
"directory": "utils/api-tests"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "rm -rf tests && node script.mjs && vitest run --config ./vitest.config.ts"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@salutejs/plasma-b2c": "1.613.0-canary.2420.23801489438.0",
|
|
17
|
+
"@salutejs/plasma-giga": "0.340.0-canary.2420.23801489438.0",
|
|
18
|
+
"@salutejs/plasma-icons": "1.234.0-canary.2420.23801489438.0",
|
|
19
|
+
"@salutejs/plasma-web": "1.615.0-canary.2420.23801489438.0",
|
|
20
|
+
"@salutejs/sdds-bizcom": "0.345.0-canary.2420.23801489438.0",
|
|
21
|
+
"@salutejs/sdds-cs": "0.349.0-canary.2420.23801489438.0",
|
|
22
|
+
"@salutejs/sdds-dfa": "0.343.0-canary.2420.23801489438.0",
|
|
23
|
+
"@salutejs/sdds-finai": "0.336.0-canary.2420.23801489438.0",
|
|
24
|
+
"@salutejs/sdds-insol": "0.340.0-canary.2420.23801489438.0",
|
|
25
|
+
"@salutejs/sdds-netology": "0.344.0-canary.2420.23801489438.0",
|
|
26
|
+
"@salutejs/sdds-platform-ai": "0.344.0-canary.2420.23801489438.0",
|
|
27
|
+
"@salutejs/sdds-scan": "0.343.0-canary.2420.23801489438.0",
|
|
28
|
+
"@salutejs/sdds-serv": "0.344.0-canary.2420.23801489438.0",
|
|
29
|
+
"@types/react": "18.0.28",
|
|
30
|
+
"@types/react-dom": "18.0.11",
|
|
31
|
+
"react": "18.2.0",
|
|
32
|
+
"react-dom": "18.2.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"gitHead": "f3b2e40fa8039e6ea8e1e6ebfae162910a29dac1"
|
|
38
|
+
}
|
package/script.mjs
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* Скрипт для подготовки файлов с тестами под разные библиотеки.
|
|
2
|
+
* basicLib - библиотека для исходных файлов. Компоненты для тестов должны браться только из нее.
|
|
3
|
+
* libs - массив с библиотеками, в которых будет проверяться API.
|
|
4
|
+
* Происходит это заменой импорта с basicLib на нужную в данный момент библиотеку.
|
|
5
|
+
* Далее скрипт генерирует файлы на основе этих мета-данных и уже после этого запускается тестирование. */
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
const config = {
|
|
12
|
+
basicLib: '@salutejs/plasma-b2c',
|
|
13
|
+
libs: [
|
|
14
|
+
{
|
|
15
|
+
name: '@salutejs/plasma-b2c',
|
|
16
|
+
ignoreComponents: ['Combobox', 'TextField'],
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: '@salutejs/plasma-web',
|
|
20
|
+
ignoreComponents: ['Combobox', 'TextField'],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: '@salutejs/plasma-giga',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: '@salutejs/sdds-bizcom',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: '@salutejs/sdds-cs',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: '@salutejs/sdds-dfa',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: '@salutejs/sdds-finai',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: '@salutejs/sdds-insol',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: '@salutejs/sdds-netology',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: '@salutejs/sdds-platform-ai',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: '@salutejs/sdds-scan',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: '@salutejs/sdds-serv',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
ignoreComponents: [],
|
|
54
|
+
srcDir: 'src',
|
|
55
|
+
outDir: 'tests',
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
(() => {
|
|
59
|
+
function getFiles(dir) {
|
|
60
|
+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
61
|
+
const fullPath = path.join(dir, entry.name);
|
|
62
|
+
return entry.isDirectory() ? getFiles(fullPath) : fullPath;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const filename = fileURLToPath(import.meta.url);
|
|
68
|
+
const dirname = path.dirname(filename);
|
|
69
|
+
|
|
70
|
+
const SRC_DIR = path.resolve(dirname, config.srcDir);
|
|
71
|
+
const OUT_DIR = path.resolve(dirname, config.outDir);
|
|
72
|
+
|
|
73
|
+
const files = getFiles(SRC_DIR);
|
|
74
|
+
|
|
75
|
+
files.forEach((filePath) => {
|
|
76
|
+
if (
|
|
77
|
+
Array.isArray(config.ignoreComponents) &&
|
|
78
|
+
config.ignoreComponents.some((component) => filePath.includes(`src/components/${component}`))
|
|
79
|
+
) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const relPath = path.relative(SRC_DIR, filePath);
|
|
84
|
+
const originalContent = fs.readFileSync(filePath, 'utf8');
|
|
85
|
+
|
|
86
|
+
config.libs.forEach(({ name, ignoreComponents }) => {
|
|
87
|
+
if (
|
|
88
|
+
Array.isArray(ignoreComponents) &&
|
|
89
|
+
ignoreComponents.some((component) => filePath.includes(`src/components/${component}`))
|
|
90
|
+
) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const libFolder = name.replace('@salutejs/', '');
|
|
95
|
+
const targetPath = path.join(OUT_DIR, libFolder, relPath);
|
|
96
|
+
|
|
97
|
+
const transformedContent = originalContent.replace(new RegExp(config.basicLib, 'g'), name);
|
|
98
|
+
|
|
99
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
100
|
+
fs.writeFileSync(targetPath, transformedContent);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
console.log('Файлы для тестов сгенерированы успешно');
|
|
105
|
+
} catch (err) {
|
|
106
|
+
console.error('Ошибка генерации тестов: ', err);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
})();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ComponentProps, ReactNode, CSSProperties, AriaRole } from 'react';
|
|
3
|
+
import { describe, it } from 'vitest';
|
|
4
|
+
import { expectTypeOf } from 'expect-type';
|
|
5
|
+
import { IconDownload } from '@salutejs/plasma-icons';
|
|
6
|
+
import { Button } from '@salutejs/plasma-b2c';
|
|
7
|
+
|
|
8
|
+
type ButtonProps = ComponentProps<typeof Button>;
|
|
9
|
+
|
|
10
|
+
describe('Basics', () => {
|
|
11
|
+
it('Common', () => {
|
|
12
|
+
expectTypeOf<ButtonProps>().toHaveProperty('children').toEqualTypeOf<ReactNode>();
|
|
13
|
+
expectTypeOf<ButtonProps>().toHaveProperty('text').toEqualTypeOf<string | undefined>();
|
|
14
|
+
expectTypeOf<ButtonProps>().toHaveProperty('contentLeft').toEqualTypeOf<ReactNode>();
|
|
15
|
+
expectTypeOf<ButtonProps>().toHaveProperty('contentPlacing').toEqualTypeOf<'default' | 'relaxed' | undefined>();
|
|
16
|
+
expectTypeOf<ButtonProps>().toHaveProperty('additionalContent').toEqualTypeOf<ReactNode>();
|
|
17
|
+
expectTypeOf<ButtonProps>().toHaveProperty('isLoading').toEqualTypeOf<boolean | undefined>();
|
|
18
|
+
expectTypeOf<ButtonProps>().toHaveProperty('loader').toEqualTypeOf<ReactNode>();
|
|
19
|
+
expectTypeOf<ButtonProps>().toHaveProperty('stretch').toEqualTypeOf<boolean | undefined>();
|
|
20
|
+
expectTypeOf<ButtonProps>()
|
|
21
|
+
.toHaveProperty('stretching')
|
|
22
|
+
.toEqualTypeOf<'fixed' | 'filled' | 'auto' | undefined>();
|
|
23
|
+
expectTypeOf<ButtonProps>().toHaveProperty('square').toEqualTypeOf<boolean | undefined>();
|
|
24
|
+
expectTypeOf<ButtonProps>().toHaveProperty('focused').toEqualTypeOf<boolean | undefined>();
|
|
25
|
+
expectTypeOf<ButtonProps>().toHaveProperty('disabled').toEqualTypeOf<boolean | undefined>();
|
|
26
|
+
expectTypeOf<ButtonProps>()
|
|
27
|
+
.toHaveProperty('pin')
|
|
28
|
+
.toEqualTypeOf<
|
|
29
|
+
| 'square-square'
|
|
30
|
+
| 'square-clear'
|
|
31
|
+
| 'clear-square'
|
|
32
|
+
| 'clear-clear'
|
|
33
|
+
| 'clear-circle'
|
|
34
|
+
| 'circle-clear'
|
|
35
|
+
| 'circle-circle'
|
|
36
|
+
| undefined
|
|
37
|
+
>();
|
|
38
|
+
expectTypeOf<ButtonProps>().toHaveProperty('outlined').toEqualTypeOf<boolean | undefined>();
|
|
39
|
+
expectTypeOf<ButtonProps>().toHaveProperty('shiftLeft').toEqualTypeOf<boolean | undefined>();
|
|
40
|
+
expectTypeOf<ButtonProps>().toHaveProperty('shiftRight').toEqualTypeOf<boolean | undefined>();
|
|
41
|
+
expectTypeOf<ButtonProps>().toHaveProperty('blur').toEqualTypeOf<'small' | 'medium' | 'large' | undefined>();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('Variations', () => {
|
|
45
|
+
type View = NonNullable<ButtonProps['view']>;
|
|
46
|
+
expectTypeOf<View>().toExtend<string>();
|
|
47
|
+
expectTypeOf<string>().not.toExtend<View>();
|
|
48
|
+
|
|
49
|
+
type Size = NonNullable<ButtonProps['size']>;
|
|
50
|
+
expectTypeOf<Size>().toExtend<string>();
|
|
51
|
+
expectTypeOf<string>().not.toExtend<Size>();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('HTMLInputElement', () => {
|
|
55
|
+
expectTypeOf<ButtonProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
|
|
56
|
+
expectTypeOf<ButtonProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
|
|
57
|
+
expectTypeOf<ButtonProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
|
|
58
|
+
expectTypeOf<ButtonProps>()
|
|
59
|
+
.toHaveProperty('onClick')
|
|
60
|
+
.toEqualTypeOf<React.MouseEventHandler<HTMLElement> | undefined>();
|
|
61
|
+
expectTypeOf<ButtonProps>()
|
|
62
|
+
.toHaveProperty('onMouseEnter')
|
|
63
|
+
.toEqualTypeOf<React.MouseEventHandler<HTMLElement> | undefined>();
|
|
64
|
+
expectTypeOf<ButtonProps>()
|
|
65
|
+
.toHaveProperty('onMouseLeave')
|
|
66
|
+
.toEqualTypeOf<React.MouseEventHandler<HTMLElement> | undefined>();
|
|
67
|
+
expectTypeOf<ButtonProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
|
|
68
|
+
expectTypeOf<ButtonProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('Unions', () => {
|
|
73
|
+
it('RightContent', () => {
|
|
74
|
+
expectTypeOf<ButtonProps>({ value: 123 });
|
|
75
|
+
expectTypeOf<ButtonProps>({ contentRight: 123 });
|
|
76
|
+
// @ts-expect-error
|
|
77
|
+
expectTypeOf<ButtonProps>({ value: 123, contentRight: 123 });
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('Complex', () => {
|
|
82
|
+
it('Examples', () => {
|
|
83
|
+
expectTypeOf<ButtonProps>({ text: 'Текст', contentLeft: <IconDownload color="inherit" /> });
|
|
84
|
+
expectTypeOf<ButtonProps>({ isLoading: true, loader: <div>Loader...</div> });
|
|
85
|
+
expectTypeOf<ButtonProps>({ text: 'Button', stretching: 'filled' });
|
|
86
|
+
expectTypeOf<ButtonProps>({ text: 'Hello', value: 'Plasma', stretching: 'filled', contentPlacing: 'default' });
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ComponentProps, ReactNode, CSSProperties, AriaRole } from 'react';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { describe, it } from 'vitest';
|
|
5
|
+
import { expectTypeOf } from 'expect-type';
|
|
6
|
+
import { Checkbox } from '@salutejs/plasma-b2c';
|
|
7
|
+
|
|
8
|
+
type CheckboxProps = ComponentProps<typeof Checkbox>;
|
|
9
|
+
|
|
10
|
+
describe('Basics', () => {
|
|
11
|
+
it('Common', () => {
|
|
12
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('label').toEqualTypeOf<ReactNode>();
|
|
13
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('description').toEqualTypeOf<ReactNode>();
|
|
14
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('singleLine').toEqualTypeOf<boolean | undefined>();
|
|
15
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('indeterminate').toEqualTypeOf<boolean | undefined>();
|
|
16
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('focused').toEqualTypeOf<boolean | undefined>();
|
|
17
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('disabled').toEqualTypeOf<boolean | undefined>();
|
|
18
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('checked').toEqualTypeOf<boolean | undefined>();
|
|
19
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('readOnly').toEqualTypeOf<boolean | undefined>();
|
|
20
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('required').toEqualTypeOf<boolean | undefined>();
|
|
21
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('name').toEqualTypeOf<string | undefined>();
|
|
22
|
+
expectTypeOf<CheckboxProps>()
|
|
23
|
+
.toHaveProperty('value')
|
|
24
|
+
.toEqualTypeOf<string | number | readonly string[] | undefined>();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('Variations', () => {
|
|
28
|
+
type View = NonNullable<CheckboxProps['view']>;
|
|
29
|
+
expectTypeOf<View>().toExtend<string>();
|
|
30
|
+
expectTypeOf<string>().not.toExtend<View>();
|
|
31
|
+
|
|
32
|
+
type Size = NonNullable<CheckboxProps['size']>;
|
|
33
|
+
expectTypeOf<Size>().toExtend<string>();
|
|
34
|
+
expectTypeOf<string>().not.toExtend<Size>();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('HTMLInputElement', () => {
|
|
38
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
|
|
39
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
|
|
40
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
|
|
41
|
+
expectTypeOf<CheckboxProps>()
|
|
42
|
+
.toHaveProperty('onChange')
|
|
43
|
+
.toEqualTypeOf<React.ChangeEventHandler<HTMLInputElement> | undefined>();
|
|
44
|
+
expectTypeOf<CheckboxProps>()
|
|
45
|
+
.toHaveProperty('onFocus')
|
|
46
|
+
.toEqualTypeOf<React.FocusEventHandler<HTMLInputElement> | undefined>();
|
|
47
|
+
expectTypeOf<CheckboxProps>()
|
|
48
|
+
.toHaveProperty('onBlur')
|
|
49
|
+
.toEqualTypeOf<React.FocusEventHandler<HTMLInputElement> | undefined>();
|
|
50
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
|
|
51
|
+
expectTypeOf<CheckboxProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('Complex', () => {
|
|
56
|
+
it('Examples', () => {
|
|
57
|
+
expectTypeOf<CheckboxProps>({ label: 'Согласен с условиями' });
|
|
58
|
+
expectTypeOf<CheckboxProps>({ label: 'Пункт', description: 'Описание пункта' });
|
|
59
|
+
expectTypeOf<CheckboxProps>({ label: 'Пункт', description: 'Описание', singleLine: true });
|
|
60
|
+
expectTypeOf<CheckboxProps>({ label: 'Частично', indeterminate: true });
|
|
61
|
+
expectTypeOf<CheckboxProps>({ label: 'Неактивен', disabled: true, checked: true });
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('Examples', () => {
|
|
66
|
+
it('Controlled', () => {
|
|
67
|
+
() => {
|
|
68
|
+
const [checked, setChecked] = useState(false);
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<Checkbox
|
|
72
|
+
label="Согласен с условиями"
|
|
73
|
+
checked={checked}
|
|
74
|
+
onChange={(e) => setChecked(e.target.checked)}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('With description', () => {
|
|
81
|
+
() => {
|
|
82
|
+
return <Checkbox label="Получать уведомления" description="На почту и в приложение" />;
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('Indeterminate', () => {
|
|
87
|
+
() => {
|
|
88
|
+
return <Checkbox label="Выбрать все" indeterminate />;
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('Disabled', () => {
|
|
93
|
+
() => {
|
|
94
|
+
return <Checkbox label="Неактивный" disabled checked />;
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('SingleLine', () => {
|
|
99
|
+
() => {
|
|
100
|
+
return <Checkbox label="Длинный заголовок" description="Длинное описание" singleLine />;
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AriaRole,
|
|
3
|
+
ComponentProps,
|
|
4
|
+
CSSProperties,
|
|
5
|
+
ReactElement,
|
|
6
|
+
RefObject,
|
|
7
|
+
ReactNode,
|
|
8
|
+
ChangeEventHandler,
|
|
9
|
+
} from 'react';
|
|
10
|
+
import React, { useState, useRef } from 'react';
|
|
11
|
+
import { describe, it } from 'vitest';
|
|
12
|
+
import { expectTypeOf } from 'expect-type';
|
|
13
|
+
import { Combobox } from '@salutejs/plasma-b2c';
|
|
14
|
+
|
|
15
|
+
type ComboboxProps = ComponentProps<typeof Combobox>;
|
|
16
|
+
|
|
17
|
+
type ItemOption = {
|
|
18
|
+
value: string;
|
|
19
|
+
label: string;
|
|
20
|
+
placement?:
|
|
21
|
+
| 'top'
|
|
22
|
+
| 'top-start'
|
|
23
|
+
| 'top-end'
|
|
24
|
+
| 'right'
|
|
25
|
+
| 'right-start'
|
|
26
|
+
| 'right-end'
|
|
27
|
+
| 'bottom'
|
|
28
|
+
| 'bottom-start'
|
|
29
|
+
| 'bottom-end'
|
|
30
|
+
| 'left'
|
|
31
|
+
| 'left-start'
|
|
32
|
+
| 'left-end';
|
|
33
|
+
items?: Array<ItemOption>;
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
contentLeft?: ReactNode;
|
|
36
|
+
contentRight?: ReactNode;
|
|
37
|
+
className?: string;
|
|
38
|
+
listMaxHeight?: CSSProperties['height'];
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
describe('Basics', () => {
|
|
42
|
+
it('Common', () => {
|
|
43
|
+
// @ts-expect-error
|
|
44
|
+
expectTypeOf<ComboboxProps>({});
|
|
45
|
+
// @ts-expect-error
|
|
46
|
+
expectTypeOf<ComboboxProps>({ placement: 'bottom' });
|
|
47
|
+
expectTypeOf<ComboboxProps>({ items: [] });
|
|
48
|
+
expectTypeOf<ComboboxProps>()
|
|
49
|
+
.toHaveProperty('placement')
|
|
50
|
+
.toEqualTypeOf<
|
|
51
|
+
| 'top'
|
|
52
|
+
| 'top-start'
|
|
53
|
+
| 'top-end'
|
|
54
|
+
| 'right'
|
|
55
|
+
| 'right-start'
|
|
56
|
+
| 'right-end'
|
|
57
|
+
| 'bottom'
|
|
58
|
+
| 'bottom-start'
|
|
59
|
+
| 'bottom-end'
|
|
60
|
+
| 'left'
|
|
61
|
+
| 'left-start'
|
|
62
|
+
| 'left-end'
|
|
63
|
+
| undefined
|
|
64
|
+
>();
|
|
65
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('placeholder').toEqualTypeOf<string | undefined>();
|
|
66
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('helperText').toEqualTypeOf<string | undefined>();
|
|
67
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('contentLeft').toEqualTypeOf<ReactElement | undefined>();
|
|
68
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('textBefore').toEqualTypeOf<string | undefined>();
|
|
69
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('textAfter').toEqualTypeOf<string | undefined>();
|
|
70
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('variant').toEqualTypeOf<'normal' | 'tight' | undefined>();
|
|
71
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('zIndex').toEqualTypeOf<CSSProperties['zIndex'] | undefined>();
|
|
72
|
+
expectTypeOf<ComboboxProps>()
|
|
73
|
+
.toHaveProperty('listMaxHeight')
|
|
74
|
+
.toEqualTypeOf<CSSProperties['height'] | undefined>();
|
|
75
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('listWidth').toEqualTypeOf<CSSProperties['width'] | undefined>();
|
|
76
|
+
expectTypeOf<ComboboxProps>()
|
|
77
|
+
.toHaveProperty('portal')
|
|
78
|
+
.toEqualTypeOf<string | RefObject<HTMLElement> | undefined>();
|
|
79
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('closeAfterSelect').toEqualTypeOf<boolean | undefined>();
|
|
80
|
+
expectTypeOf<ComboboxProps>()
|
|
81
|
+
.toHaveProperty('onChangeValue')
|
|
82
|
+
.toEqualTypeOf<((value: string) => void) | undefined>();
|
|
83
|
+
expectTypeOf<ComboboxProps>()
|
|
84
|
+
.toHaveProperty('filterValue')
|
|
85
|
+
.toEqualTypeOf<((value: string) => boolean) | undefined>();
|
|
86
|
+
// TODO: Сузить тип для onScroll
|
|
87
|
+
// expectTypeOf<ComboboxProps>()
|
|
88
|
+
// .toHaveProperty('onScroll')
|
|
89
|
+
// .toEqualTypeOf<((e: UIEvent<HTMLElement>) => void) | undefined>();
|
|
90
|
+
expectTypeOf<ComboboxProps>()
|
|
91
|
+
.toHaveProperty('onToggle')
|
|
92
|
+
.toEqualTypeOf<((isOpen: boolean) => void) | undefined>();
|
|
93
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('beforeList').toEqualTypeOf<ReactNode | undefined>();
|
|
94
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('afterList').toEqualTypeOf<ReactNode | undefined>();
|
|
95
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('virtual').toEqualTypeOf<boolean | undefined>();
|
|
96
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('mode').toEqualTypeOf<'default' | 'radio' | undefined>();
|
|
97
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('emptyStateDescription').toEqualTypeOf<ReactNode | undefined>();
|
|
98
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('treeView').toEqualTypeOf<boolean | undefined>();
|
|
99
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('arrowPlacement').toEqualTypeOf<'left' | 'right' | undefined>();
|
|
100
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('listHeight').toEqualTypeOf<CSSProperties['height'] | undefined>();
|
|
101
|
+
expectTypeOf<ComboboxProps>()
|
|
102
|
+
.toHaveProperty('listOverflow')
|
|
103
|
+
.toEqualTypeOf<CSSProperties['overflow'] | undefined>();
|
|
104
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('label').toEqualTypeOf<string | undefined>();
|
|
105
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('keepPlaceholder').toEqualTypeOf<boolean | undefined>();
|
|
106
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('readOnly').toEqualTypeOf<boolean | undefined>();
|
|
107
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('disabled').toEqualTypeOf<boolean | undefined>();
|
|
108
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('alwaysOpened').toEqualTypeOf<boolean | undefined>();
|
|
109
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('name').toEqualTypeOf<string | undefined>();
|
|
110
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('defaultValue').toEqualTypeOf<string | string[] | undefined>();
|
|
111
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('multiple').toEqualTypeOf<boolean | undefined>();
|
|
112
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('value').toEqualTypeOf<string | string[] | undefined>();
|
|
113
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('isTargetAmount').toEqualTypeOf<boolean | undefined>();
|
|
114
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('targetAmount').toEqualTypeOf<number | undefined>();
|
|
115
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('selectAllOptions').toEqualTypeOf<
|
|
116
|
+
| {
|
|
117
|
+
checked?: boolean;
|
|
118
|
+
indeterminate?: boolean;
|
|
119
|
+
label?: string;
|
|
120
|
+
onClick?: () => void;
|
|
121
|
+
sticky?: boolean;
|
|
122
|
+
}
|
|
123
|
+
| undefined
|
|
124
|
+
>();
|
|
125
|
+
expectTypeOf<ComboboxProps>()
|
|
126
|
+
.toHaveProperty('chipClickArea')
|
|
127
|
+
.toEqualTypeOf<'full' | 'close-icon' | undefined>();
|
|
128
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('required').toEqualTypeOf<boolean | undefined>();
|
|
129
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('requiredPlacement').toEqualTypeOf<'left' | 'right' | undefined>();
|
|
130
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('optional').toEqualTypeOf<boolean | undefined>();
|
|
131
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('optionalText').toEqualTypeOf<string | undefined>();
|
|
132
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hasRequiredIndicator').toEqualTypeOf<boolean | undefined>();
|
|
133
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hintText').toEqualTypeOf<string | undefined>();
|
|
134
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hintTrigger').toEqualTypeOf<'hover' | 'click' | undefined>();
|
|
135
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hintTargetIcon').toEqualTypeOf<ReactNode | undefined>();
|
|
136
|
+
// TODO: Почему свойства нет в sdds-insol?
|
|
137
|
+
// expectTypeOf<ComboboxProps>()
|
|
138
|
+
// .toHaveProperty('hintTargetPlacement')
|
|
139
|
+
// .toEqualTypeOf<'inner' | 'outer' | undefined>();
|
|
140
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hintHasArrow').toEqualTypeOf<boolean | undefined>();
|
|
141
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hintOffset').toEqualTypeOf<[number, number] | undefined>();
|
|
142
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hintWidth').toEqualTypeOf<string | undefined>();
|
|
143
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('hintContentLeft').toEqualTypeOf<ReactNode | undefined>();
|
|
144
|
+
const items = [{ value: '', label: '', randomProp: '' }];
|
|
145
|
+
// @ts-expect-error
|
|
146
|
+
expectTypeOf<ComboboxProps>({ items: [{ value: '' }] });
|
|
147
|
+
// @ts-expect-error
|
|
148
|
+
expectTypeOf<ComboboxProps>({ items: [{ label: '' }] });
|
|
149
|
+
expectTypeOf<ComboboxProps>({ items: [{ value: '', label: '' }] });
|
|
150
|
+
expectTypeOf<ComboboxProps>({ items });
|
|
151
|
+
expectTypeOf<ComboboxProps>({ items: [{ value: '', label: '', disabled: true }] });
|
|
152
|
+
expectTypeOf<ComboboxProps>({ items: [{ value: '', label: '', disabled: true }] });
|
|
153
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('items').toEqualTypeOf<ItemOption[]>();
|
|
154
|
+
expectTypeOf<ComboboxProps>()
|
|
155
|
+
.toHaveProperty('renderItem')
|
|
156
|
+
.toEqualTypeOf<((item: ItemOption) => ReactNode) | undefined>();
|
|
157
|
+
expectTypeOf<ComboboxProps>()
|
|
158
|
+
.toHaveProperty('filter')
|
|
159
|
+
.toEqualTypeOf<((item: ItemOption, textValue: string) => boolean) | undefined>();
|
|
160
|
+
expectTypeOf<ComboboxProps>()
|
|
161
|
+
.toHaveProperty('onChange')
|
|
162
|
+
.toEqualTypeOf<
|
|
163
|
+
| ((value: string[], item: ItemOption | null) => void)
|
|
164
|
+
| ((value: string, item: ItemOption | null) => void)
|
|
165
|
+
| ChangeEventHandler
|
|
166
|
+
| undefined
|
|
167
|
+
>();
|
|
168
|
+
expectTypeOf<ComboboxProps>()
|
|
169
|
+
.toHaveProperty('renderValue')
|
|
170
|
+
.toEqualTypeOf<((item: ItemOption) => string) | undefined>();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('Variations', () => {
|
|
174
|
+
type View = NonNullable<ComboboxProps['view']>;
|
|
175
|
+
expectTypeOf<View>().toExtend<string>();
|
|
176
|
+
expectTypeOf<string>().not.toExtend<View>();
|
|
177
|
+
|
|
178
|
+
type Size = NonNullable<ComboboxProps['size']>;
|
|
179
|
+
expectTypeOf<Size>().toExtend<string>();
|
|
180
|
+
expectTypeOf<string>().not.toExtend<Size>();
|
|
181
|
+
|
|
182
|
+
type LabelPlacement = NonNullable<ComboboxProps['labelPlacement']>;
|
|
183
|
+
expectTypeOf<LabelPlacement>().toExtend<string>();
|
|
184
|
+
expectTypeOf<string>().not.toExtend<LabelPlacement>();
|
|
185
|
+
// TODO: Почему свойств hintView и hintSize нет в sdds-insol?
|
|
186
|
+
// type HintView = NonNullable<ComboboxProps['hintView']>;
|
|
187
|
+
// expectTypeOf<HintView>().toExtend<string>();
|
|
188
|
+
// expectTypeOf<string>().not.toExtend<HintView>();
|
|
189
|
+
//
|
|
190
|
+
// type HintSize = NonNullable<ComboboxProps['hintSize']>;
|
|
191
|
+
// expectTypeOf<HintSize>().toExtend<string>();
|
|
192
|
+
// expectTypeOf<string>().not.toExtend<HintSize>();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('HTMLInputElement', () => {
|
|
196
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
|
|
197
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
|
|
198
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
|
|
199
|
+
expectTypeOf<ComboboxProps>()
|
|
200
|
+
.toHaveProperty('onFocus')
|
|
201
|
+
.toEqualTypeOf<React.FocusEventHandler<HTMLInputElement> | undefined>();
|
|
202
|
+
expectTypeOf<ComboboxProps>()
|
|
203
|
+
.toHaveProperty('onBlur')
|
|
204
|
+
.toEqualTypeOf<React.FocusEventHandler<HTMLInputElement> | undefined>();
|
|
205
|
+
expectTypeOf<ComboboxProps>()
|
|
206
|
+
.toHaveProperty('onKeyDown')
|
|
207
|
+
.toEqualTypeOf<React.KeyboardEventHandler<HTMLInputElement> | undefined>();
|
|
208
|
+
expectTypeOf<ComboboxProps>()
|
|
209
|
+
.toHaveProperty('onKeyUp')
|
|
210
|
+
.toEqualTypeOf<React.KeyboardEventHandler<HTMLInputElement> | undefined>();
|
|
211
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('placeholder').toEqualTypeOf<string | undefined>();
|
|
212
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
|
|
213
|
+
expectTypeOf<ComboboxProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('Unions', () => {
|
|
218
|
+
it('ViewStateProps', () => {
|
|
219
|
+
expectTypeOf<ComboboxProps>({ items: [], readOnly: true, disabled: true, alwaysOpened: false });
|
|
220
|
+
expectTypeOf<ComboboxProps>({ items: [], readOnly: false, disabled: false, alwaysOpened: true });
|
|
221
|
+
// TODO: Неправильная работа юниона ViewStateProps. Должна быть ошибка.
|
|
222
|
+
expectTypeOf<ComboboxProps>({ items: [], readOnly: false, disabled: false, alwaysOpened: false });
|
|
223
|
+
// TODO: Неправильная работа юниона ViewStateProps. Должна быть ошибка.
|
|
224
|
+
expectTypeOf<ComboboxProps>({ items: [], readOnly: true, disabled: true, alwaysOpened: true });
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('IsMultiselect', () => {
|
|
228
|
+
expectTypeOf<ComboboxProps>({ items: [], value: '' });
|
|
229
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: [] });
|
|
230
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: [''] });
|
|
231
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, onChange: (value: string[]) => {} });
|
|
232
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: false, onChange: (value: string) => {} });
|
|
233
|
+
// @ts-expect-error
|
|
234
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: false, value: [] });
|
|
235
|
+
// @ts-expect-error
|
|
236
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: false, onChange: (value: string[]) => {} });
|
|
237
|
+
// @ts-expect-error
|
|
238
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: '' });
|
|
239
|
+
// @ts-expect-error
|
|
240
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, onChange: (value: string) => {} });
|
|
241
|
+
expectTypeOf<ComboboxProps>({ items: [], isTargetAmount: false });
|
|
242
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, isTargetAmount: true });
|
|
243
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, targetAmount: 1 });
|
|
244
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, renderValue: () => '' });
|
|
245
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, selectAllOptions: { checked: true } });
|
|
246
|
+
expectTypeOf<ComboboxProps>({ items: [], multiple: true, chipClickArea: 'full' });
|
|
247
|
+
// @ts-expect-error
|
|
248
|
+
expectTypeOf<ComboboxProps>({ items: [], isTargetAmount: true });
|
|
249
|
+
// @ts-expect-error
|
|
250
|
+
expectTypeOf<ComboboxProps>({ items: [], targetAmount: 1 });
|
|
251
|
+
// @ts-expect-error
|
|
252
|
+
expectTypeOf<ComboboxProps>({ items: [], renderValue: () => '' });
|
|
253
|
+
// @ts-expect-error
|
|
254
|
+
expectTypeOf<ComboboxProps>({ items: [], selectAllOptions: { checked: true } });
|
|
255
|
+
// @ts-expect-error
|
|
256
|
+
expectTypeOf<ComboboxProps>({ items: [], chipClickArea: 'full' });
|
|
257
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', defaultValue: '' });
|
|
258
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, defaultValue: [''] });
|
|
259
|
+
// @ts-expect-error
|
|
260
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', value: '' });
|
|
261
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, isTargetAmount: true });
|
|
262
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, targetAmount: 1 });
|
|
263
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, renderValue: () => '' });
|
|
264
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, selectAllOptions: { checked: true } });
|
|
265
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, chipClickArea: 'full' });
|
|
266
|
+
// @ts-expect-error
|
|
267
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', isTargetAmount: true });
|
|
268
|
+
// @ts-expect-error
|
|
269
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', targetAmount: 1 });
|
|
270
|
+
// @ts-expect-error
|
|
271
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', renderValue: () => '' });
|
|
272
|
+
// @ts-expect-error
|
|
273
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', selectAllOptions: { checked: true } });
|
|
274
|
+
// @ts-expect-error
|
|
275
|
+
expectTypeOf<ComboboxProps>({ items: [], name: '', chipClickArea: 'full' });
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
describe('Generics', () => {
|
|
280
|
+
it('ItemOption', () => {
|
|
281
|
+
const items = [{ value: '', label: '', randomProp: '', boolProp: true }];
|
|
282
|
+
|
|
283
|
+
void (<Combobox items={items} />);
|
|
284
|
+
void (
|
|
285
|
+
<Combobox
|
|
286
|
+
multiple
|
|
287
|
+
items={items}
|
|
288
|
+
renderItem={(item) => {
|
|
289
|
+
return item.randomProp;
|
|
290
|
+
}}
|
|
291
|
+
filter={(item) => item.boolProp}
|
|
292
|
+
onChange={(value: string[], item) => {
|
|
293
|
+
return item && item.randomProp;
|
|
294
|
+
}}
|
|
295
|
+
renderValue={(item) => {
|
|
296
|
+
return item.randomProp;
|
|
297
|
+
}}
|
|
298
|
+
/>
|
|
299
|
+
);
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
describe('Examples', () => {
|
|
304
|
+
const items = [
|
|
305
|
+
{
|
|
306
|
+
value: 'north_america',
|
|
307
|
+
label: 'Северная Америка',
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
value: 'south_america',
|
|
311
|
+
label: 'Южная Америка',
|
|
312
|
+
items: [
|
|
313
|
+
{
|
|
314
|
+
value: 'brazil',
|
|
315
|
+
label: 'Бразилия',
|
|
316
|
+
disabled: true,
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
value: 'argentina',
|
|
320
|
+
label: 'Аргентина',
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
},
|
|
324
|
+
];
|
|
325
|
+
|
|
326
|
+
it('Single', () => {
|
|
327
|
+
() => {
|
|
328
|
+
const [value, setValue] = useState<string>('');
|
|
329
|
+
|
|
330
|
+
return (
|
|
331
|
+
<Combobox
|
|
332
|
+
items={items}
|
|
333
|
+
value={value}
|
|
334
|
+
onChange={setValue}
|
|
335
|
+
placeholder="Placeholder"
|
|
336
|
+
label="Label"
|
|
337
|
+
helperText="Helper text"
|
|
338
|
+
/>
|
|
339
|
+
);
|
|
340
|
+
};
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('Multiple', () => {
|
|
344
|
+
() => {
|
|
345
|
+
const [value, setValue] = useState<string[]>([]);
|
|
346
|
+
|
|
347
|
+
return (
|
|
348
|
+
<Combobox
|
|
349
|
+
multiple
|
|
350
|
+
items={items}
|
|
351
|
+
value={value}
|
|
352
|
+
onChange={setValue}
|
|
353
|
+
placeholder="Placeholder"
|
|
354
|
+
label="Label"
|
|
355
|
+
helperText="Helper text"
|
|
356
|
+
/>
|
|
357
|
+
);
|
|
358
|
+
};
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('Predefined', () => {
|
|
362
|
+
() => {
|
|
363
|
+
const [multipleValue, setMultipleValue] = useState<string[]>(['brazil', 'north_america']);
|
|
364
|
+
|
|
365
|
+
return (
|
|
366
|
+
<Combobox
|
|
367
|
+
multiple
|
|
368
|
+
items={items}
|
|
369
|
+
value={multipleValue}
|
|
370
|
+
onChange={setMultipleValue}
|
|
371
|
+
placeholder="Placeholder"
|
|
372
|
+
label="Label"
|
|
373
|
+
helperText="Helper text"
|
|
374
|
+
/>
|
|
375
|
+
);
|
|
376
|
+
};
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it('Portal', () => {
|
|
380
|
+
() => {
|
|
381
|
+
const [value, setValue] = useState<string>('');
|
|
382
|
+
|
|
383
|
+
const ref = useRef(null);
|
|
384
|
+
|
|
385
|
+
return (
|
|
386
|
+
<Combobox
|
|
387
|
+
items={items}
|
|
388
|
+
value={value}
|
|
389
|
+
onChange={setValue}
|
|
390
|
+
placeholder="Placeholder"
|
|
391
|
+
label="Label"
|
|
392
|
+
helperText="Helper text"
|
|
393
|
+
portal={ref}
|
|
394
|
+
listWidth="300px"
|
|
395
|
+
/>
|
|
396
|
+
);
|
|
397
|
+
};
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it('Uncontrolled', () => {
|
|
401
|
+
() => {
|
|
402
|
+
return <Combobox items={items} placeholder="Placeholder" label="Label" helperText="Helper text" />;
|
|
403
|
+
};
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it('Uncontrolled', () => {
|
|
407
|
+
() => {
|
|
408
|
+
const items = Array(5000)
|
|
409
|
+
.fill(1)
|
|
410
|
+
.map((_, i) => ({ value: i.toString(), label: i.toString() }));
|
|
411
|
+
|
|
412
|
+
return (
|
|
413
|
+
<Combobox
|
|
414
|
+
items={items}
|
|
415
|
+
virtual
|
|
416
|
+
listMaxHeight="200px"
|
|
417
|
+
placeholder="Placeholder"
|
|
418
|
+
label="Label"
|
|
419
|
+
helperText="Helper text"
|
|
420
|
+
/>
|
|
421
|
+
);
|
|
422
|
+
};
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
it('Disabled elements', () => {
|
|
426
|
+
() => {
|
|
427
|
+
const [value, setValue] = useState(['brazil']);
|
|
428
|
+
|
|
429
|
+
return (
|
|
430
|
+
<Combobox
|
|
431
|
+
multiple
|
|
432
|
+
label="Label"
|
|
433
|
+
placeholder="Placeholder"
|
|
434
|
+
items={items}
|
|
435
|
+
value={value}
|
|
436
|
+
onChange={setValue}
|
|
437
|
+
isTargetAmount
|
|
438
|
+
/>
|
|
439
|
+
);
|
|
440
|
+
};
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('Treeview', () => {
|
|
444
|
+
() => {
|
|
445
|
+
return (
|
|
446
|
+
<Combobox
|
|
447
|
+
multiple
|
|
448
|
+
treeView
|
|
449
|
+
label="Введите 'Токио'"
|
|
450
|
+
placeholder="Placeholder"
|
|
451
|
+
items={items}
|
|
452
|
+
listMaxHeight="300px"
|
|
453
|
+
/>
|
|
454
|
+
);
|
|
455
|
+
};
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it('Native form', () => {
|
|
459
|
+
() => {
|
|
460
|
+
return (
|
|
461
|
+
<form>
|
|
462
|
+
<Combobox label="Combobox" name="combobox" defaultValue="brazil" items={items} />
|
|
463
|
+
<Combobox label="Combobox" name="comboboxMulti" defaultValue={['brazil']} items={items} multiple />
|
|
464
|
+
</form>
|
|
465
|
+
);
|
|
466
|
+
};
|
|
467
|
+
});
|
|
468
|
+
});
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ComponentProps, ReactNode, CSSProperties, AriaRole, ReactElement, KeyboardEvent } from 'react';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { describe, it } from 'vitest';
|
|
5
|
+
import { expectTypeOf } from 'expect-type';
|
|
6
|
+
import { TextField } from '@salutejs/plasma-b2c';
|
|
7
|
+
|
|
8
|
+
type TextFieldProps = ComponentProps<typeof TextField>;
|
|
9
|
+
|
|
10
|
+
describe('Basics', () => {
|
|
11
|
+
it('Common', () => {
|
|
12
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('label').toEqualTypeOf<string | undefined>();
|
|
13
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('placeholder').toEqualTypeOf<string | undefined>();
|
|
14
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('leftHelper').toEqualTypeOf<ReactNode>();
|
|
15
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('titleCaption').toEqualTypeOf<ReactNode>();
|
|
16
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('contentLeft').toEqualTypeOf<ReactElement | undefined>();
|
|
17
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('contentRight').toEqualTypeOf<ReactElement | undefined>();
|
|
18
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('textBefore').toEqualTypeOf<string | undefined>();
|
|
19
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('textAfter').toEqualTypeOf<string | undefined>();
|
|
20
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('appearance').toEqualTypeOf<'default' | 'clear' | undefined>();
|
|
21
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('disabled').toEqualTypeOf<boolean | undefined>();
|
|
22
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('readOnly').toEqualTypeOf<boolean | undefined>();
|
|
23
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('keepPlaceholder').toEqualTypeOf<boolean | undefined>();
|
|
24
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('required').toEqualTypeOf<boolean | undefined>();
|
|
25
|
+
expectTypeOf<TextFieldProps>()
|
|
26
|
+
.toHaveProperty('requiredPlacement')
|
|
27
|
+
.toEqualTypeOf<'left' | 'right' | undefined>();
|
|
28
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('optional').toEqualTypeOf<boolean | undefined>();
|
|
29
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('optionalText').toEqualTypeOf<string | undefined>();
|
|
30
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hasRequiredIndicator').toEqualTypeOf<boolean | undefined>();
|
|
31
|
+
expectTypeOf<TextFieldProps>()
|
|
32
|
+
.toHaveProperty('onSearch')
|
|
33
|
+
.toEqualTypeOf<((value: string, event?: KeyboardEvent<HTMLInputElement>) => void) | undefined>();
|
|
34
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hintText').toEqualTypeOf<string | undefined>();
|
|
35
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hintTrigger').toEqualTypeOf<'hover' | 'click' | undefined>();
|
|
36
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hintTargetIcon').toEqualTypeOf<ReactNode>();
|
|
37
|
+
expectTypeOf<TextFieldProps>()
|
|
38
|
+
.toHaveProperty('hintTargetPlacement')
|
|
39
|
+
.toEqualTypeOf<'inner' | 'outer' | undefined>();
|
|
40
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hintHasArrow').toEqualTypeOf<boolean | undefined>();
|
|
41
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hintOffset').toEqualTypeOf<[number, number] | undefined>();
|
|
42
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hintWidth').toEqualTypeOf<string | undefined>();
|
|
43
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('hintContentLeft').toEqualTypeOf<ReactNode>();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('Variations', () => {
|
|
47
|
+
type View = NonNullable<TextFieldProps['view']>;
|
|
48
|
+
expectTypeOf<View>().toExtend<string>();
|
|
49
|
+
expectTypeOf<string>().not.toExtend<View>();
|
|
50
|
+
|
|
51
|
+
type Size = NonNullable<TextFieldProps['size']>;
|
|
52
|
+
expectTypeOf<Size>().toExtend<string>();
|
|
53
|
+
expectTypeOf<string>().not.toExtend<Size>();
|
|
54
|
+
|
|
55
|
+
type LabelPlacement = NonNullable<TextFieldProps['labelPlacement']>;
|
|
56
|
+
expectTypeOf<LabelPlacement>().toExtend<string>();
|
|
57
|
+
expectTypeOf<string>().not.toExtend<LabelPlacement>();
|
|
58
|
+
|
|
59
|
+
type HintView = NonNullable<TextFieldProps['hintView']>;
|
|
60
|
+
expectTypeOf<HintView>().toExtend<string>();
|
|
61
|
+
expectTypeOf<string>().not.toExtend<HintView>();
|
|
62
|
+
|
|
63
|
+
type HintSize = NonNullable<TextFieldProps['hintSize']>;
|
|
64
|
+
expectTypeOf<HintSize>().toExtend<string>();
|
|
65
|
+
expectTypeOf<string>().not.toExtend<HintSize>();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('HTMLInputElement', () => {
|
|
69
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
|
|
70
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
|
|
71
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
|
|
72
|
+
expectTypeOf<TextFieldProps>()
|
|
73
|
+
.toHaveProperty('value')
|
|
74
|
+
.toEqualTypeOf<string | number | readonly string[] | undefined>();
|
|
75
|
+
expectTypeOf<TextFieldProps>()
|
|
76
|
+
.toHaveProperty('defaultValue')
|
|
77
|
+
.toEqualTypeOf<string | number | readonly string[] | undefined>();
|
|
78
|
+
expectTypeOf<TextFieldProps>()
|
|
79
|
+
.toHaveProperty('onChange')
|
|
80
|
+
.toEqualTypeOf<React.ChangeEventHandler<HTMLInputElement> | undefined>();
|
|
81
|
+
expectTypeOf<TextFieldProps>()
|
|
82
|
+
.toHaveProperty('onFocus')
|
|
83
|
+
.toEqualTypeOf<React.FocusEventHandler<HTMLInputElement> | undefined>();
|
|
84
|
+
expectTypeOf<TextFieldProps>()
|
|
85
|
+
.toHaveProperty('onBlur')
|
|
86
|
+
.toEqualTypeOf<React.FocusEventHandler<HTMLInputElement> | undefined>();
|
|
87
|
+
expectTypeOf<TextFieldProps>()
|
|
88
|
+
.toHaveProperty('onKeyDown')
|
|
89
|
+
.toEqualTypeOf<React.KeyboardEventHandler<HTMLInputElement> | undefined>();
|
|
90
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
|
|
91
|
+
expectTypeOf<TextFieldProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe('Unions', () => {
|
|
96
|
+
it('ClearProps', () => {
|
|
97
|
+
expectTypeOf<TextFieldProps>({ clear: true, hasDivider: true });
|
|
98
|
+
expectTypeOf<TextFieldProps>({ clear: true, hasDivider: false });
|
|
99
|
+
expectTypeOf<TextFieldProps>({ clear: true });
|
|
100
|
+
// TODO: Неправильная работа юниона ClearProps. Должна быть ошибка.
|
|
101
|
+
expectTypeOf<TextFieldProps>({ hasDivider: true });
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('HintProps', () => {
|
|
105
|
+
expectTypeOf<TextFieldProps>({ hintText: 'hint' });
|
|
106
|
+
expectTypeOf<TextFieldProps>({ hintText: 'hint', hintTrigger: 'hover' });
|
|
107
|
+
expectTypeOf<TextFieldProps>({ hintText: 'hint', hintHasArrow: true });
|
|
108
|
+
expectTypeOf<TextFieldProps>({ hintText: 'hint', hintOffset: [0, 8] });
|
|
109
|
+
expectTypeOf<TextFieldProps>({ hintText: 'hint', hintWidth: '10rem' });
|
|
110
|
+
expectTypeOf<TextFieldProps>({});
|
|
111
|
+
// @ts-expect-error
|
|
112
|
+
expectTypeOf<TextFieldProps>({ hintTrigger: 'hover' });
|
|
113
|
+
// @ts-expect-error
|
|
114
|
+
expectTypeOf<TextFieldProps>({ hintHasArrow: true });
|
|
115
|
+
// @ts-expect-error
|
|
116
|
+
expectTypeOf<TextFieldProps>({ hintOffset: [0, 8] });
|
|
117
|
+
// @ts-expect-error
|
|
118
|
+
expectTypeOf<TextFieldProps>({ hintWidth: '10rem' });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('EnumerationType', () => {
|
|
122
|
+
expectTypeOf<TextFieldProps>({ enumerationType: 'plain' });
|
|
123
|
+
expectTypeOf<TextFieldProps>({ enumerationType: 'chip', chips: ['tag1', 'tag2'] });
|
|
124
|
+
expectTypeOf<TextFieldProps>({
|
|
125
|
+
enumerationType: 'chip',
|
|
126
|
+
chips: ['tag1'],
|
|
127
|
+
onChangeChips: (value) => {},
|
|
128
|
+
chipType: 'default',
|
|
129
|
+
});
|
|
130
|
+
expectTypeOf<TextFieldProps>({
|
|
131
|
+
enumerationType: 'chip',
|
|
132
|
+
chips: ['tag1'],
|
|
133
|
+
chipView: 'secondary',
|
|
134
|
+
});
|
|
135
|
+
expectTypeOf<TextFieldProps>({
|
|
136
|
+
enumerationType: 'chip',
|
|
137
|
+
chips: ['tag1'],
|
|
138
|
+
chipValidator: (value) => ({ view: 'default' }),
|
|
139
|
+
});
|
|
140
|
+
expectTypeOf<TextFieldProps>({
|
|
141
|
+
enumerationType: 'chip',
|
|
142
|
+
chipType: 'text',
|
|
143
|
+
});
|
|
144
|
+
// @ts-expect-error
|
|
145
|
+
expectTypeOf<TextFieldProps>({ enumerationType: 'plain', chips: ['tag1'] });
|
|
146
|
+
// @ts-expect-error
|
|
147
|
+
expectTypeOf<TextFieldProps>({ enumerationType: 'plain', onChangeChips: (value: any[]) => {} });
|
|
148
|
+
// @ts-expect-error
|
|
149
|
+
expectTypeOf<TextFieldProps>({ enumerationType: 'plain', chipType: 'default' });
|
|
150
|
+
// @ts-expect-error
|
|
151
|
+
expectTypeOf<TextFieldProps>({ enumerationType: 'plain', chipView: 'secondary' });
|
|
152
|
+
// @ts-expect-error
|
|
153
|
+
expectTypeOf<TextFieldProps>({ enumerationType: 'plain', chipValidator: (value: string) => ({}) });
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('Complex', () => {
|
|
158
|
+
it('Examples', () => {
|
|
159
|
+
expectTypeOf<TextFieldProps>({
|
|
160
|
+
label: 'Имя',
|
|
161
|
+
placeholder: 'Введите имя',
|
|
162
|
+
leftHelper: 'Обязательное поле',
|
|
163
|
+
});
|
|
164
|
+
expectTypeOf<TextFieldProps>({
|
|
165
|
+
label: 'Email',
|
|
166
|
+
placeholder: 'Введите email',
|
|
167
|
+
leftHelper: 'Некорректный email',
|
|
168
|
+
required: true,
|
|
169
|
+
requiredPlacement: 'right',
|
|
170
|
+
});
|
|
171
|
+
expectTypeOf<TextFieldProps>({
|
|
172
|
+
label: 'Tags',
|
|
173
|
+
enumerationType: 'chip',
|
|
174
|
+
chips: ['tag1', 'tag2'],
|
|
175
|
+
onChangeChips: (values) => {},
|
|
176
|
+
});
|
|
177
|
+
expectTypeOf<TextFieldProps>({
|
|
178
|
+
label: 'С подсказкой',
|
|
179
|
+
hintText: 'Это подсказка',
|
|
180
|
+
hintTrigger: 'hover',
|
|
181
|
+
hintView: 'default',
|
|
182
|
+
hintSize: 's',
|
|
183
|
+
});
|
|
184
|
+
expectTypeOf<TextFieldProps>({
|
|
185
|
+
label: 'Clear',
|
|
186
|
+
appearance: 'clear',
|
|
187
|
+
clear: true,
|
|
188
|
+
hasDivider: true,
|
|
189
|
+
});
|
|
190
|
+
expectTypeOf<TextFieldProps>({
|
|
191
|
+
textBefore: '$',
|
|
192
|
+
textAfter: 'USD',
|
|
193
|
+
placeholder: '0.00',
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
describe('Examples', () => {
|
|
199
|
+
it('Basic', () => {
|
|
200
|
+
() => {
|
|
201
|
+
const [value, setValue] = useState('');
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<TextField
|
|
205
|
+
value={value}
|
|
206
|
+
onChange={(e) => setValue(e.target.value)}
|
|
207
|
+
label="Имя"
|
|
208
|
+
placeholder="Введите имя"
|
|
209
|
+
leftHelper="Обязательное поле"
|
|
210
|
+
/>
|
|
211
|
+
);
|
|
212
|
+
};
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('With chips', () => {
|
|
216
|
+
() => {
|
|
217
|
+
const [chips, setChips] = useState<Array<string | number | boolean>>(['tag1', 'tag2']);
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<TextField
|
|
221
|
+
label="Tags"
|
|
222
|
+
enumerationType="chip"
|
|
223
|
+
chips={chips}
|
|
224
|
+
onChangeChips={setChips}
|
|
225
|
+
chipType="default"
|
|
226
|
+
/>
|
|
227
|
+
);
|
|
228
|
+
};
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('With hint', () => {
|
|
232
|
+
() => {
|
|
233
|
+
return (
|
|
234
|
+
<TextField
|
|
235
|
+
label="С подсказкой"
|
|
236
|
+
hintText="Это подсказка"
|
|
237
|
+
hintTrigger="hover"
|
|
238
|
+
hintView="default"
|
|
239
|
+
hintSize="s"
|
|
240
|
+
hintHasArrow
|
|
241
|
+
placeholder="Введите значение"
|
|
242
|
+
/>
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('Clear appearance', () => {
|
|
248
|
+
() => {
|
|
249
|
+
return <TextField label="Clear" appearance="clear" clear hasDivider placeholder="Введите значение" />;
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('With text decorations', () => {
|
|
254
|
+
() => {
|
|
255
|
+
return <TextField textBefore="$" textAfter="USD" placeholder="0.00" label="Сумма" />;
|
|
256
|
+
};
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('Disabled and readOnly', () => {
|
|
260
|
+
() => {
|
|
261
|
+
return (
|
|
262
|
+
<>
|
|
263
|
+
<TextField label="Disabled" disabled value="Нельзя редактировать" />
|
|
264
|
+
<TextField label="ReadOnly" readOnly value="Только чтение" />
|
|
265
|
+
</>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('With onSearch', () => {
|
|
271
|
+
() => {
|
|
272
|
+
return (
|
|
273
|
+
<TextField
|
|
274
|
+
label="Поиск"
|
|
275
|
+
placeholder="Введите запрос"
|
|
276
|
+
onSearch={(value) => {
|
|
277
|
+
console.log(value);
|
|
278
|
+
}}
|
|
279
|
+
/>
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES5",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
6
|
+
"jsx": "react",
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"importHelpers": false,
|
|
10
|
+
"typeRoots": ["node_modules/@types"],
|
|
11
|
+
|
|
12
|
+
/* Strict Type-Checking Options */
|
|
13
|
+
"strict": true,
|
|
14
|
+
"noImplicitAny": false,
|
|
15
|
+
"strictNullChecks": true,
|
|
16
|
+
"strictFunctionTypes": true,
|
|
17
|
+
"strictBindCallApply": true,
|
|
18
|
+
"strictPropertyInitialization": true,
|
|
19
|
+
"noImplicitThis": true,
|
|
20
|
+
"alwaysStrict": true,
|
|
21
|
+
"isolatedModules": true,
|
|
22
|
+
|
|
23
|
+
/* Additional Checks */
|
|
24
|
+
"noUnusedLocals": false,
|
|
25
|
+
"noUnusedParameters": false,
|
|
26
|
+
"noImplicitReturns": true,
|
|
27
|
+
"noFallthroughCasesInSwitch": true,
|
|
28
|
+
|
|
29
|
+
/* Module Resolution Options */
|
|
30
|
+
"moduleResolution": "bundler",
|
|
31
|
+
"esModuleInterop": true,
|
|
32
|
+
|
|
33
|
+
/* Advanced Options */
|
|
34
|
+
"skipLibCheck": true,
|
|
35
|
+
"skipDefaultLibCheck": true,
|
|
36
|
+
"forceConsistentCasingInFileNames": true
|
|
37
|
+
},
|
|
38
|
+
"include": ["./src", "./tests"],
|
|
39
|
+
"exclude": ["node_modules/*"]
|
|
40
|
+
}
|