@salutejs/sdds-api-tests 0.7.0-next-platform-ai.0 → 0.8.0-dev.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.
@@ -0,0 +1,171 @@
1
+ import * as React from 'react';
2
+ import type { ComponentProps, ReactNode, CSSProperties, AriaRole } from 'react';
3
+ import { describe, it } from 'node:test';
4
+ import { expectTypeOf } from 'expect-type';
5
+ import { InformationWrapper } from '@salutejs/plasma-b2c';
6
+
7
+ type InformationWrapperProps = ComponentProps<typeof InformationWrapper>;
8
+
9
+ describe('Basics', () => {
10
+ it('Common', () => {
11
+ // Layout
12
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('children').toEqualTypeOf<ReactNode>();
13
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('label').toEqualTypeOf<string | undefined>();
14
+ expectTypeOf<InformationWrapperProps>()
15
+ .toHaveProperty('labelPlacement')
16
+ .toEqualTypeOf<'top' | 'left' | undefined>();
17
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('labelHtmlFor').toEqualTypeOf<string | undefined>();
18
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('titleCaption').toEqualTypeOf<ReactNode>();
19
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('leftHelper').toEqualTypeOf<ReactNode>();
20
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('rightHelper').toEqualTypeOf<ReactNode>();
21
+
22
+ // Form-related
23
+ expectTypeOf<InformationWrapperProps>()
24
+ .toHaveProperty('hasRequiredIndicator')
25
+ .toEqualTypeOf<boolean | undefined>();
26
+ expectTypeOf<InformationWrapperProps>()
27
+ .toHaveProperty('requiredIndicatorPlacement')
28
+ .toEqualTypeOf<'right' | 'left' | undefined>();
29
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('optional').toEqualTypeOf<boolean | undefined>();
30
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('optionalText').toEqualTypeOf<string | undefined>();
31
+
32
+ // State
33
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('disabled').toEqualTypeOf<boolean | undefined>();
34
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('readOnly').toEqualTypeOf<boolean | undefined>();
35
+
36
+ // Hint
37
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('hintText').toEqualTypeOf<string | undefined>();
38
+ expectTypeOf<InformationWrapperProps>()
39
+ .toHaveProperty('hintTrigger')
40
+ .toEqualTypeOf<'hover' | 'click' | undefined>();
41
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('hintOpened').toEqualTypeOf<boolean | undefined>();
42
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('hintTargetIcon').toEqualTypeOf<ReactNode>();
43
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('hintHasArrow').toEqualTypeOf<boolean | undefined>();
44
+ expectTypeOf<InformationWrapperProps>()
45
+ .toHaveProperty('hintOffset')
46
+ .toEqualTypeOf<[number, number] | undefined>();
47
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('hintWidth').toEqualTypeOf<string | undefined>();
48
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('hintContentLeft').toEqualTypeOf<ReactNode>();
49
+ });
50
+
51
+ it('Variations', () => {
52
+ type View = NonNullable<InformationWrapperProps['view']>;
53
+ expectTypeOf<View>().toExtend<string>();
54
+ expectTypeOf<string>().not.toExtend<View>();
55
+
56
+ type Size = NonNullable<InformationWrapperProps['size']>;
57
+ expectTypeOf<Size>().toExtend<string>();
58
+ expectTypeOf<string>().not.toExtend<Size>();
59
+
60
+ type HintView = NonNullable<InformationWrapperProps['hintView']>;
61
+ expectTypeOf<HintView>().toExtend<string>();
62
+ expectTypeOf<string>().not.toExtend<HintView>();
63
+
64
+ type HintSize = NonNullable<InformationWrapperProps['hintSize']>;
65
+ expectTypeOf<HintSize>().toExtend<string>();
66
+ expectTypeOf<string>().not.toExtend<HintSize>();
67
+ });
68
+
69
+ it('HTMLDivElement', () => {
70
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
71
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
72
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
73
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
74
+ expectTypeOf<InformationWrapperProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
75
+ expectTypeOf<InformationWrapperProps>()
76
+ .toHaveProperty('onClick')
77
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
78
+ expectTypeOf<InformationWrapperProps>()
79
+ .toHaveProperty('onMouseEnter')
80
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
81
+ expectTypeOf<InformationWrapperProps>()
82
+ .toHaveProperty('onMouseLeave')
83
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
84
+ });
85
+ });
86
+
87
+ describe('Unions', () => {
88
+ it('HintProps', () => {
89
+ // Valid: with hintText, all hint-related props are available
90
+ expectTypeOf<InformationWrapperProps>({ hintText: 'Текст подсказки' });
91
+ expectTypeOf<InformationWrapperProps>({
92
+ hintText: 'Текст подсказки',
93
+ hintTrigger: 'hover',
94
+ hintHasArrow: true,
95
+ hintWidth: '10rem',
96
+ });
97
+
98
+ // Valid: without any hint props
99
+ expectTypeOf<InformationWrapperProps>({ label: 'Лейбл' });
100
+
101
+ // Неправильная работа юниона HintProps. Должна быть ошибка при передаче hint-пропсов без hintText.
102
+ // @ts-expect-error
103
+ expectTypeOf<InformationWrapperProps>({ hintTrigger: 'hover' });
104
+ });
105
+ });
106
+
107
+ describe('Examples', () => {
108
+ it('Basic', () => {
109
+ () => {
110
+ return (
111
+ <InformationWrapper label="Лейбл" labelPlacement="top">
112
+ <div />
113
+ </InformationWrapper>
114
+ );
115
+ };
116
+ });
117
+
118
+ it('With hint', () => {
119
+ () => {
120
+ return (
121
+ <InformationWrapper
122
+ label="Лейбл"
123
+ titleCaption="Подпись к полю"
124
+ leftHelper="Подсказка слева"
125
+ rightHelper="Подсказка справа"
126
+ hintText="Текст подсказки"
127
+ hintTrigger="hover"
128
+ hintHasArrow
129
+ hintWidth="10rem"
130
+ >
131
+ <div />
132
+ </InformationWrapper>
133
+ );
134
+ };
135
+ });
136
+
137
+ it('Required indicator', () => {
138
+ () => {
139
+ return (
140
+ <InformationWrapper
141
+ label="Лейбл"
142
+ hasRequiredIndicator
143
+ requiredIndicatorPlacement="right"
144
+ labelPlacement="top"
145
+ >
146
+ <div />
147
+ </InformationWrapper>
148
+ );
149
+ };
150
+ });
151
+
152
+ it('Optional', () => {
153
+ () => {
154
+ return (
155
+ <InformationWrapper label="Лейбл" optional optionalText="опционально">
156
+ <div />
157
+ </InformationWrapper>
158
+ );
159
+ };
160
+ });
161
+
162
+ it('Disabled', () => {
163
+ () => {
164
+ return (
165
+ <InformationWrapper label="Лейбл" disabled>
166
+ <div />
167
+ </InformationWrapper>
168
+ );
169
+ };
170
+ });
171
+ });
@@ -0,0 +1,172 @@
1
+ import React, { useState } from 'react';
2
+ import type { ComponentProps, ReactNode, CSSProperties, AriaRole, RefObject, SyntheticEvent, Ref } from 'react';
3
+ import { describe, it } from 'node:test';
4
+ import { expectTypeOf } from 'expect-type';
5
+ import { Popover } from '@salutejs/plasma-b2c';
6
+ import type { PopoverPlacement, PopoverTrigger } from '@salutejs/plasma-b2c';
7
+
8
+ type PopoverProps = ComponentProps<typeof Popover>;
9
+
10
+ describe('Basics', () => {
11
+ it('Common', () => {
12
+ // layout
13
+ expectTypeOf<PopoverProps>().toHaveProperty('target').toEqualTypeOf<ReactNode | Ref<HTMLElement> | undefined>();
14
+ expectTypeOf<PopoverProps>().toHaveProperty('offset').toEqualTypeOf<[number, number] | undefined>();
15
+ expectTypeOf<PopoverProps>()
16
+ .toHaveProperty('frame')
17
+ .toEqualTypeOf<string | RefObject<HTMLElement> | undefined>();
18
+ expectTypeOf<PopoverProps>().toHaveProperty('hasArrow').toEqualTypeOf<boolean | undefined>();
19
+ expectTypeOf<PopoverProps>().toHaveProperty('zIndex').toEqualTypeOf<string | undefined>();
20
+ expectTypeOf<PopoverProps>().toHaveProperty('preventOverflow').toEqualTypeOf<boolean | undefined>();
21
+ expectTypeOf<PopoverProps>().toHaveProperty('usePortal').toEqualTypeOf<boolean | undefined>();
22
+ expectTypeOf<PopoverProps>().toHaveProperty('animated').toEqualTypeOf<boolean | undefined>();
23
+
24
+ // state / behaviour
25
+ expectTypeOf<PopoverProps>().toHaveProperty('opened').toEqualTypeOf<boolean | undefined>();
26
+ expectTypeOf<PopoverProps>().toHaveProperty('trigger').toEqualTypeOf<PopoverTrigger | undefined>();
27
+ expectTypeOf<PopoverProps>().toHaveProperty('isFocusTrapped').toEqualTypeOf<boolean | undefined>();
28
+ expectTypeOf<PopoverProps>().toHaveProperty('closeOnEsc').toEqualTypeOf<boolean | undefined>();
29
+ expectTypeOf<PopoverProps>().toHaveProperty('closeOnOverlayClick').toEqualTypeOf<boolean | undefined>();
30
+
31
+ // content slots
32
+ expectTypeOf<PopoverProps>().toHaveProperty('children').toEqualTypeOf<ReactNode>();
33
+
34
+ // callbacks
35
+ expectTypeOf<PopoverProps>()
36
+ .toHaveProperty('onToggle')
37
+ .toEqualTypeOf<((isOpen: boolean, event: SyntheticEvent | Event) => void) | undefined>();
38
+ });
39
+
40
+ it('Placement', () => {
41
+ type PlacementProp = NonNullable<PopoverProps['placement']>;
42
+ expectTypeOf<PlacementProp>().toExtend<string | readonly string[]>();
43
+ expectTypeOf<string>().not.toExtend<PlacementProp>();
44
+
45
+ // accepts known placement values
46
+ expectTypeOf<PopoverProps>({ placement: 'top' as PopoverPlacement });
47
+ expectTypeOf<PopoverProps>({ placement: 'bottom-start' as PopoverPlacement });
48
+ });
49
+
50
+ it('HTMLDivElement', () => {
51
+ expectTypeOf<PopoverProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
52
+ expectTypeOf<PopoverProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
53
+ expectTypeOf<PopoverProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
54
+ expectTypeOf<PopoverProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
55
+ expectTypeOf<PopoverProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
56
+ expectTypeOf<PopoverProps>()
57
+ .toHaveProperty('onClick')
58
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
59
+ expectTypeOf<PopoverProps>()
60
+ .toHaveProperty('onMouseEnter')
61
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
62
+ expectTypeOf<PopoverProps>()
63
+ .toHaveProperty('onMouseLeave')
64
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
65
+ });
66
+ });
67
+
68
+ describe('Resizable', () => {
69
+ it('resizable prop accepts boolean', () => {
70
+ expectTypeOf<PopoverProps>({ resizable: true });
71
+ expectTypeOf<PopoverProps>({ resizable: false });
72
+ });
73
+
74
+ it('resizable prop accepts config object', () => {
75
+ expectTypeOf<PopoverProps>({
76
+ resizable: {
77
+ disabled: false,
78
+ directions: ['bottom-right'],
79
+ defaultSize: { width: 200, height: 100 },
80
+ minWidth: 100,
81
+ minHeight: 50,
82
+ maxWidth: 600,
83
+ maxHeight: 400,
84
+ iconSize: 's',
85
+ hiddenIcons: ['top-left'],
86
+ },
87
+ });
88
+ });
89
+
90
+ it('iconSize is narrowed', () => {
91
+ type ResizableObj = Extract<NonNullable<PopoverProps['resizable']>, object>;
92
+ expectTypeOf<ResizableObj>().toHaveProperty('iconSize').toEqualTypeOf<'xs' | 's' | 'm' | undefined>();
93
+ });
94
+ });
95
+
96
+ describe('Examples', () => {
97
+ it('Click trigger', () => {
98
+ () => {
99
+ const [isOpen, setIsOpen] = useState(false);
100
+ return (
101
+ <Popover
102
+ opened={isOpen}
103
+ onToggle={(is) => setIsOpen(is)}
104
+ trigger="click"
105
+ placement="bottom"
106
+ hasArrow
107
+ target={<button type="button">Open</button>}
108
+ >
109
+ <div>Content</div>
110
+ </Popover>
111
+ );
112
+ };
113
+ });
114
+
115
+ it('Hover trigger with offset', () => {
116
+ () => {
117
+ const [isOpen, setIsOpen] = useState(false);
118
+ return (
119
+ <Popover
120
+ opened={isOpen}
121
+ onToggle={(is) => setIsOpen(is)}
122
+ trigger="hover"
123
+ placement="top"
124
+ offset={[0, 8]}
125
+ closeOnEsc={false}
126
+ isFocusTrapped={false}
127
+ >
128
+ Content
129
+ </Popover>
130
+ );
131
+ };
132
+ });
133
+
134
+ it('Resizable', () => {
135
+ () => {
136
+ const [isOpen, setIsOpen] = useState(false);
137
+ return (
138
+ <Popover
139
+ opened={isOpen}
140
+ onToggle={(is) => setIsOpen(is)}
141
+ trigger="click"
142
+ resizable={{ disabled: false, directions: ['bottom-right'], iconSize: 's' }}
143
+ onResizeStart={() => {}}
144
+ onResizeEnd={() => {}}
145
+ >
146
+ Content
147
+ </Popover>
148
+ );
149
+ };
150
+ });
151
+
152
+ it('Overlay click and frame', () => {
153
+ () => {
154
+ const [isOpen, setIsOpen] = useState(false);
155
+ const ref = React.useRef<HTMLDivElement>(null);
156
+ return (
157
+ <div ref={ref}>
158
+ <Popover
159
+ opened={isOpen}
160
+ onToggle={(is) => setIsOpen(is)}
161
+ trigger="click"
162
+ closeOnOverlayClick
163
+ frame={ref}
164
+ animated
165
+ >
166
+ Content
167
+ </Popover>
168
+ </div>
169
+ );
170
+ };
171
+ });
172
+ });
@@ -9,7 +9,7 @@ import type {
9
9
  RefObject,
10
10
  } from 'react';
11
11
  import { useRef, useState } from 'react';
12
- import { describe, it } from 'vitest';
12
+ import { describe, it } from 'node:test';
13
13
  import { expectTypeOf } from 'expect-type';
14
14
  import { Controller, useForm } from 'react-hook-form';
15
15
  import { Button, Cell, Select } from '@salutejs/plasma-b2c';
@@ -51,7 +51,7 @@ describe('Basics', () => {
51
51
  expectTypeOf<SelectProps>().toHaveProperty('listWidth').toEqualTypeOf<CSSProperties['width'] | undefined>();
52
52
  expectTypeOf<SelectProps>()
53
53
  .toHaveProperty('portal')
54
- .toEqualTypeOf<string | RefObject<HTMLElement> | undefined>();
54
+ .toEqualTypeOf<string | RefObject<HTMLElement | null> | undefined>();
55
55
  expectTypeOf<SelectProps>()
56
56
  .toHaveProperty('renderValue')
57
57
  .toEqualTypeOf<((item: ItemOption) => string) | undefined>();
@@ -0,0 +1,220 @@
1
+ import * as React from 'react';
2
+ import type { ComponentProps, CSSProperties, AriaRole } from 'react';
3
+ import { describe, it } from 'node:test';
4
+ import { expectTypeOf } from 'expect-type';
5
+ import { LineSkeleton, RectSkeleton, TextSkeleton, withSkeleton } from '@salutejs/plasma-b2c';
6
+ import type { WithSkeletonProps } from '@salutejs/plasma-b2c';
7
+
8
+ type LineSkeletonProps = ComponentProps<typeof LineSkeleton>;
9
+ type RectSkeletonProps = ComponentProps<typeof RectSkeleton>;
10
+ type TextSkeletonProps = ComponentProps<typeof TextSkeleton>;
11
+
12
+ describe('LineSkeleton', () => {
13
+ it('Common', () => {
14
+ expectTypeOf<LineSkeletonProps>()
15
+ .toHaveProperty('animationType')
16
+ .toEqualTypeOf<'shimmer' | 'pulse' | undefined>();
17
+ expectTypeOf<LineSkeletonProps>()
18
+ .toHaveProperty('roundness')
19
+ .toEqualTypeOf<0 | 4 | 8 | 12 | 14 | 16 | 18 | 20 | 24 | 28 | 32 | 250 | undefined>();
20
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('lighter').toEqualTypeOf<boolean | undefined>();
21
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('customGradientColor').toEqualTypeOf<string | undefined>();
22
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('customFadeInColor').toEqualTypeOf<string | undefined>();
23
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('customFadeOutColor').toEqualTypeOf<string | undefined>();
24
+ });
25
+
26
+ it('HTMLDivElement', () => {
27
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
28
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
29
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
30
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
31
+ expectTypeOf<LineSkeletonProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
32
+ expectTypeOf<LineSkeletonProps>()
33
+ .toHaveProperty('onClick')
34
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
35
+ });
36
+ });
37
+
38
+ describe('RectSkeleton', () => {
39
+ it('Common', () => {
40
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('width').toEqualTypeOf<string | number>();
41
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('height').toEqualTypeOf<string | number>();
42
+ expectTypeOf<RectSkeletonProps>()
43
+ .toHaveProperty('animationType')
44
+ .toEqualTypeOf<'shimmer' | 'pulse' | undefined>();
45
+ expectTypeOf<RectSkeletonProps>()
46
+ .toHaveProperty('roundness')
47
+ .toEqualTypeOf<0 | 4 | 8 | 12 | 14 | 16 | 18 | 20 | 24 | 28 | 32 | 250 | undefined>();
48
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('lighter').toEqualTypeOf<boolean | undefined>();
49
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('customGradientColor').toEqualTypeOf<string | undefined>();
50
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('customFadeInColor').toEqualTypeOf<string | undefined>();
51
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('customFadeOutColor').toEqualTypeOf<string | undefined>();
52
+ });
53
+
54
+ it('HTMLDivElement', () => {
55
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
56
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
57
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
58
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
59
+ expectTypeOf<RectSkeletonProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
60
+ expectTypeOf<RectSkeletonProps>()
61
+ .toHaveProperty('onClick')
62
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
63
+ });
64
+ });
65
+
66
+ describe('TextSkeleton', () => {
67
+ it('Common', () => {
68
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('lines').toEqualTypeOf<number>();
69
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('width').toEqualTypeOf<string | number | undefined>();
70
+ expectTypeOf<TextSkeletonProps>()
71
+ .toHaveProperty('animationType')
72
+ .toEqualTypeOf<'shimmer' | 'pulse' | undefined>();
73
+ expectTypeOf<TextSkeletonProps>()
74
+ .toHaveProperty('roundness')
75
+ .toEqualTypeOf<0 | 4 | 8 | 12 | 14 | 16 | 18 | 20 | 24 | 28 | 32 | 250 | undefined>();
76
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('lighter').toEqualTypeOf<boolean | undefined>();
77
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('customGradientColor').toEqualTypeOf<string | undefined>();
78
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('customFadeInColor').toEqualTypeOf<string | undefined>();
79
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('customFadeOutColor').toEqualTypeOf<string | undefined>();
80
+ });
81
+
82
+ it('HTMLDivElement', () => {
83
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
84
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
85
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
86
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
87
+ expectTypeOf<TextSkeletonProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
88
+ expectTypeOf<TextSkeletonProps>()
89
+ .toHaveProperty('onClick')
90
+ .toEqualTypeOf<React.MouseEventHandler<HTMLDivElement> | undefined>();
91
+ });
92
+ });
93
+
94
+ describe('withSkeleton', () => {
95
+ it('Common', () => {
96
+ expectTypeOf<WithSkeletonProps>().toHaveProperty('skeleton').toEqualTypeOf<boolean | undefined>();
97
+ expectTypeOf<WithSkeletonProps>()
98
+ .toHaveProperty('animationConfig')
99
+ .toEqualTypeOf<
100
+ | { type: 'shimmer'; lighter?: boolean; customGradientColor?: string }
101
+ | { type: 'pulse'; customFadeInColor?: string; customFadeOutColor?: string }
102
+ | undefined
103
+ >();
104
+ });
105
+
106
+ it('HTMLElement', () => {
107
+ expectTypeOf<WithSkeletonProps>().toHaveProperty('id').toEqualTypeOf<string | undefined>();
108
+ expectTypeOf<WithSkeletonProps>().toHaveProperty('className').toEqualTypeOf<string | undefined>();
109
+ expectTypeOf<WithSkeletonProps>().toHaveProperty('style').toEqualTypeOf<CSSProperties | undefined>();
110
+ expectTypeOf<WithSkeletonProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
111
+ expectTypeOf<WithSkeletonProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
112
+ });
113
+ });
114
+
115
+ describe('Unions', () => {
116
+ it('AnimationConfig', () => {
117
+ // shimmer — valid combinations
118
+ expectTypeOf<WithSkeletonProps>({ animationConfig: { type: 'shimmer' } });
119
+ expectTypeOf<WithSkeletonProps>({ animationConfig: { type: 'shimmer', lighter: true } });
120
+ expectTypeOf<WithSkeletonProps>({ animationConfig: { type: 'shimmer', customGradientColor: '#fff' } });
121
+
122
+ // pulse — valid combinations
123
+ expectTypeOf<WithSkeletonProps>({ animationConfig: { type: 'pulse' } });
124
+ expectTypeOf<WithSkeletonProps>({ animationConfig: { type: 'pulse', customFadeInColor: '#f00' } });
125
+ expectTypeOf<WithSkeletonProps>({
126
+ animationConfig: { type: 'pulse', customFadeInColor: '#f00', customFadeOutColor: '#0f0' },
127
+ });
128
+
129
+ // shimmer with pulse-only field
130
+ // @ts-expect-error
131
+ expectTypeOf<WithSkeletonProps>({ animationConfig: { type: 'shimmer', customFadeInColor: '#f00' } });
132
+
133
+ // pulse with shimmer-only field
134
+ // @ts-expect-error
135
+ expectTypeOf<WithSkeletonProps>({ animationConfig: { type: 'pulse', lighter: true } });
136
+ });
137
+ });
138
+
139
+ describe('Examples', () => {
140
+ it('LineSkeleton', () => {
141
+ () => {
142
+ return (
143
+ <>
144
+ <LineSkeleton size="bodyM" />
145
+ <LineSkeleton size="h3" animationType="shimmer" roundness={16} />
146
+ <LineSkeleton
147
+ size="h3"
148
+ animationType="pulse"
149
+ customFadeInColor="#e0e0e0"
150
+ customFadeOutColor="#f5f5f5"
151
+ />
152
+ <LineSkeleton
153
+ size="bodyS"
154
+ lighter
155
+ customGradientColor="linear-gradient(90deg, #eee 0%, #fff 50%, #eee 100%)"
156
+ />
157
+ </>
158
+ );
159
+ };
160
+ });
161
+
162
+ it('RectSkeleton', () => {
163
+ () => {
164
+ return (
165
+ <>
166
+ <RectSkeleton width="12rem" height="8rem" />
167
+ <RectSkeleton width={128} height={128} roundness={8} />
168
+ <RectSkeleton width="4rem" height="4rem" animationType="pulse" />
169
+ </>
170
+ );
171
+ };
172
+ });
173
+
174
+ it('TextSkeleton', () => {
175
+ () => {
176
+ return (
177
+ <>
178
+ <TextSkeleton lines={3} size="bodyM" />
179
+ <TextSkeleton lines={5} size="textM" width={50} />
180
+ <TextSkeleton lines={3} animationType="shimmer" customGradientColor="linear-gradient()" />
181
+ </>
182
+ );
183
+ };
184
+ });
185
+
186
+ it('withSkeleton shimmer', () => {
187
+ () => {
188
+ const DivSkeleton = withSkeleton(
189
+ React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>((props, ref) => (
190
+ <div ref={ref} {...props} />
191
+ )),
192
+ );
193
+ return (
194
+ <DivSkeleton
195
+ skeleton
196
+ animationConfig={{
197
+ type: 'shimmer',
198
+ customGradientColor: 'linear-gradient(90deg, #eee, #fff, #eee)',
199
+ }}
200
+ />
201
+ );
202
+ };
203
+ });
204
+
205
+ it('withSkeleton pulse', () => {
206
+ () => {
207
+ const DivSkeleton = withSkeleton(
208
+ React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>((props, ref) => (
209
+ <div ref={ref} {...props} />
210
+ )),
211
+ );
212
+ return (
213
+ <DivSkeleton
214
+ skeleton
215
+ animationConfig={{ type: 'pulse', customFadeInColor: '#e0e0e0', customFadeOutColor: '#f5f5f5' }}
216
+ />
217
+ );
218
+ };
219
+ });
220
+ });
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import type { ComponentProps, ReactNode, CSSProperties, AriaRole, ReactElement, KeyboardEvent } from 'react';
3
3
  import { useState } from 'react';
4
- import { describe, it } from 'vitest';
4
+ import { describe, it } from 'node:test';
5
5
  import { expectTypeOf } from 'expect-type';
6
6
  import { TextField } from '@salutejs/plasma-b2c';
7
7
 
@@ -1,6 +1,6 @@
1
1
  import React, { createRef } from 'react';
2
2
  import type { ComponentProps } from 'react';
3
- import { describe, it } from 'vitest';
3
+ import { describe, it } from 'node:test';
4
4
  import { expectTypeOf } from 'expect-type';
5
5
  import { TextL } from '@salutejs/plasma-b2c';
6
6
 
package/tsconfig.json CHANGED
@@ -8,6 +8,7 @@
8
8
  "sourceMap": true,
9
9
  "importHelpers": false,
10
10
  "typeRoots": ["node_modules/@types"],
11
+ "types": ["node"],
11
12
 
12
13
  /* Strict Type-Checking Options */
13
14
  "strict": true,
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["./tests"]
4
+ }
package/vitest.config.ts DELETED
@@ -1,12 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- typecheck: {
6
- enabled: true,
7
- only: true,
8
- include: ['./tests/**/*'],
9
- ignoreSourceErrors: true,
10
- },
11
- },
12
- });