@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.
@@ -1,50 +1,29 @@
1
1
  import type {
2
2
  AriaRole,
3
+ ChangeEventHandler,
3
4
  ComponentProps,
4
5
  CSSProperties,
5
6
  ReactElement,
6
- RefObject,
7
7
  ReactNode,
8
- ChangeEventHandler,
8
+ RefObject,
9
9
  } from 'react';
10
- import React, { useState, useRef } from 'react';
11
- import { describe, it } from 'vitest';
10
+ import React, { useRef, useState } from 'react';
11
+ import { describe, it } from 'node:test';
12
12
  import { expectTypeOf } from 'expect-type';
13
- import { Combobox } from '@salutejs/plasma-b2c';
13
+ import { Controller, useForm } from 'react-hook-form';
14
+ import { Cell, Combobox, ComboboxItemOption as ItemOption } from '@salutejs/plasma-b2c';
14
15
 
15
16
  type ComboboxProps = ComponentProps<typeof Combobox>;
16
17
 
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
18
  describe('Basics', () => {
42
19
  it('Common', () => {
43
20
  // @ts-expect-error
44
21
  expectTypeOf<ComboboxProps>({});
45
- // @ts-expect-error
46
- expectTypeOf<ComboboxProps>({ placement: 'bottom' });
47
22
  expectTypeOf<ComboboxProps>({ items: [] });
23
+ expectTypeOf<ComboboxProps>().toHaveProperty('items').toEqualTypeOf<ItemOption[]>();
24
+
25
+ expectTypeOf<ComboboxProps>().toHaveProperty('treeView').toEqualTypeOf<boolean | undefined>();
26
+ expectTypeOf<ComboboxProps>().toHaveProperty('arrowPlacement').toEqualTypeOf<'left' | 'right' | undefined>();
48
27
  expectTypeOf<ComboboxProps>()
49
28
  .toHaveProperty('placement')
50
29
  .toEqualTypeOf<
@@ -62,11 +41,6 @@ describe('Basics', () => {
62
41
  | 'left-end'
63
42
  | undefined
64
43
  >();
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
44
  expectTypeOf<ComboboxProps>().toHaveProperty('variant').toEqualTypeOf<'normal' | 'tight' | undefined>();
71
45
  expectTypeOf<ComboboxProps>().toHaveProperty('zIndex').toEqualTypeOf<CSSProperties['zIndex'] | undefined>();
72
46
  expectTypeOf<ComboboxProps>()
@@ -75,61 +49,57 @@ describe('Basics', () => {
75
49
  expectTypeOf<ComboboxProps>().toHaveProperty('listWidth').toEqualTypeOf<CSSProperties['width'] | undefined>();
76
50
  expectTypeOf<ComboboxProps>()
77
51
  .toHaveProperty('portal')
78
- .toEqualTypeOf<string | RefObject<HTMLElement> | undefined>();
52
+ .toEqualTypeOf<string | RefObject<HTMLElement | null> | undefined>();
79
53
  expectTypeOf<ComboboxProps>().toHaveProperty('closeAfterSelect').toEqualTypeOf<boolean | undefined>();
54
+ expectTypeOf<ComboboxProps>().toHaveProperty('virtual').toEqualTypeOf<boolean | undefined>();
80
55
  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>();
56
+ .toHaveProperty('onScroll')
57
+ .toEqualTypeOf<((e: React.UIEvent<HTMLElement>) => void) | undefined>();
90
58
  expectTypeOf<ComboboxProps>()
91
59
  .toHaveProperty('onToggle')
92
60
  .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
61
  expectTypeOf<ComboboxProps>().toHaveProperty('mode').toEqualTypeOf<'default' | 'radio' | undefined>();
97
62
  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>();
63
+ expectTypeOf<ComboboxProps>().toHaveProperty('flip').toEqualTypeOf<boolean | undefined>();
64
+ expectTypeOf<ComboboxProps>().toHaveProperty('shift').toEqualTypeOf<boolean | undefined>();
65
+ expectTypeOf<ComboboxProps>().toHaveProperty('singleLine').toEqualTypeOf<boolean | undefined>();
106
66
  expectTypeOf<ComboboxProps>().toHaveProperty('readOnly').toEqualTypeOf<boolean | undefined>();
107
67
  expectTypeOf<ComboboxProps>().toHaveProperty('disabled').toEqualTypeOf<boolean | undefined>();
108
68
  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
- >();
69
+
70
+ expectTypeOf<ComboboxProps>().toHaveProperty('placeholder').toEqualTypeOf<string | undefined>();
71
+ expectTypeOf<ComboboxProps>().toHaveProperty('helperText').toEqualTypeOf<string | undefined>();
72
+ expectTypeOf<ComboboxProps>().toHaveProperty('contentLeft').toEqualTypeOf<ReactElement | undefined>();
73
+ expectTypeOf<ComboboxProps>().toHaveProperty('contentRight').toEqualTypeOf<ReactElement | undefined>();
74
+ expectTypeOf<ComboboxProps>().toHaveProperty('textBefore').toEqualTypeOf<string | undefined>();
75
+ expectTypeOf<ComboboxProps>().toHaveProperty('textAfter').toEqualTypeOf<string | undefined>();
76
+ expectTypeOf<ComboboxProps>().toHaveProperty('beforeList').toEqualTypeOf<ReactNode | undefined>();
77
+ expectTypeOf<ComboboxProps>().toHaveProperty('afterList').toEqualTypeOf<ReactNode | undefined>();
78
+ expectTypeOf<ComboboxProps>().toHaveProperty('label').toEqualTypeOf<string | undefined>();
79
+ expectTypeOf<ComboboxProps>().toHaveProperty('keepPlaceholder').toEqualTypeOf<boolean | undefined>();
80
+
125
81
  expectTypeOf<ComboboxProps>()
126
- .toHaveProperty('chipClickArea')
127
- .toEqualTypeOf<'full' | 'close-icon' | undefined>();
82
+ .toHaveProperty('renderItem')
83
+ .toEqualTypeOf<((item: ItemOption) => ReactNode) | undefined>();
84
+ expectTypeOf<ComboboxProps>()
85
+ .toHaveProperty('renderSelectionIcon')
86
+ .toEqualTypeOf<((selected: boolean | 'indeterminate') => ReactNode) | undefined>();
87
+ expectTypeOf<ComboboxProps>()
88
+ .toHaveProperty('filter')
89
+ .toEqualTypeOf<((item: ItemOption, textValue: string) => boolean) | undefined>();
90
+ expectTypeOf<ComboboxProps>()
91
+ .toHaveProperty('onChangeValue')
92
+ .toEqualTypeOf<((value: string) => void) | undefined>();
93
+ expectTypeOf<ComboboxProps>()
94
+ .toHaveProperty('filterValue')
95
+ .toEqualTypeOf<((value: string) => boolean) | undefined>();
96
+
128
97
  expectTypeOf<ComboboxProps>().toHaveProperty('required').toEqualTypeOf<boolean | undefined>();
129
98
  expectTypeOf<ComboboxProps>().toHaveProperty('requiredPlacement').toEqualTypeOf<'left' | 'right' | undefined>();
130
99
  expectTypeOf<ComboboxProps>().toHaveProperty('optional').toEqualTypeOf<boolean | undefined>();
131
100
  expectTypeOf<ComboboxProps>().toHaveProperty('optionalText').toEqualTypeOf<string | undefined>();
132
101
  expectTypeOf<ComboboxProps>().toHaveProperty('hasRequiredIndicator').toEqualTypeOf<boolean | undefined>();
102
+
133
103
  expectTypeOf<ComboboxProps>().toHaveProperty('hintText').toEqualTypeOf<string | undefined>();
134
104
  expectTypeOf<ComboboxProps>().toHaveProperty('hintTrigger').toEqualTypeOf<'hover' | 'click' | undefined>();
135
105
  expectTypeOf<ComboboxProps>().toHaveProperty('hintTargetIcon').toEqualTypeOf<ReactNode | undefined>();
@@ -141,33 +111,65 @@ describe('Basics', () => {
141
111
  expectTypeOf<ComboboxProps>().toHaveProperty('hintOffset').toEqualTypeOf<[number, number] | undefined>();
142
112
  expectTypeOf<ComboboxProps>().toHaveProperty('hintWidth').toEqualTypeOf<string | undefined>();
143
113
  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[]>();
114
+
115
+ expectTypeOf<ComboboxProps>().toHaveProperty('multiple').toEqualTypeOf<boolean | undefined>();
116
+ expectTypeOf<ComboboxProps>().toHaveProperty('value').toEqualTypeOf<string | string[] | undefined>();
117
+ expectTypeOf<ComboboxProps>().toHaveProperty('defaultValue').toEqualTypeOf<string | string[] | undefined>();
118
+ expectTypeOf<ComboboxProps>().toHaveProperty('name').toEqualTypeOf<string | undefined>();
119
+ expectTypeOf<ComboboxProps>().toHaveProperty('isTargetAmount').toEqualTypeOf<boolean | undefined>();
120
+ expectTypeOf<ComboboxProps>().toHaveProperty('targetAmount').toEqualTypeOf<number | undefined>();
154
121
  expectTypeOf<ComboboxProps>()
155
- .toHaveProperty('renderItem')
156
- .toEqualTypeOf<((item: ItemOption) => ReactNode) | undefined>();
122
+ .toHaveProperty('renderValue')
123
+ .toEqualTypeOf<((item: ItemOption) => string) | undefined>();
124
+ expectTypeOf<ComboboxProps>().toHaveProperty('selectAllOptions').toEqualTypeOf<
125
+ | {
126
+ checked?: boolean;
127
+ indeterminate?: boolean;
128
+ label?: string;
129
+ onClick?: () => void;
130
+ sticky?: boolean;
131
+ }
132
+ | undefined
133
+ >();
157
134
  expectTypeOf<ComboboxProps>()
158
- .toHaveProperty('filter')
159
- .toEqualTypeOf<((item: ItemOption, textValue: string) => boolean) | undefined>();
135
+ .toHaveProperty('chipClickArea')
136
+ .toEqualTypeOf<'full' | 'close-icon' | undefined>();
160
137
  expectTypeOf<ComboboxProps>()
161
138
  .toHaveProperty('onChange')
162
139
  .toEqualTypeOf<
163
- | ((value: string[], item: ItemOption | null) => void)
164
140
  | ((value: string, item: ItemOption | null) => void)
165
- | ChangeEventHandler
141
+ | ((value: string[], item: ItemOption | null) => void)
142
+ | ChangeEventHandler<HTMLSelectElement>
166
143
  | undefined
167
144
  >();
168
- expectTypeOf<ComboboxProps>()
169
- .toHaveProperty('renderValue')
170
- .toEqualTypeOf<((item: ItemOption) => string) | undefined>();
145
+ });
146
+
147
+ it('ItemOption', () => {
148
+ const items = [{ value: '', label: '', custom: '' }];
149
+
150
+ // @ts-expect-error
151
+ expectTypeOf<ComboboxProps>({ items: [{ value: '' }] });
152
+ // @ts-expect-error
153
+ expectTypeOf<ComboboxProps>({ items: [{ label: '' }] });
154
+ expectTypeOf<ComboboxProps>({ items: [{ value: '', label: '' }] });
155
+ expectTypeOf<ComboboxProps>({ items });
156
+ expectTypeOf<ComboboxProps>({
157
+ items: [
158
+ {
159
+ value: '',
160
+ label: '',
161
+ placement: 'right-start',
162
+ disabled: true,
163
+ contentLeft: null,
164
+ contentRight: null,
165
+ className: 'item',
166
+ listMaxHeight: '10rem',
167
+ items: [{ value: 'child', label: 'Child' }],
168
+ },
169
+ ],
170
+ });
171
+ // @ts-expect-error
172
+ expectTypeOf<ComboboxProps>({ items: [{ value: '', label: '', placement: 'auto' }] });
171
173
  });
172
174
 
173
175
  it('Variations', () => {
@@ -208,7 +210,6 @@ describe('Basics', () => {
208
210
  expectTypeOf<ComboboxProps>()
209
211
  .toHaveProperty('onKeyUp')
210
212
  .toEqualTypeOf<React.KeyboardEventHandler<HTMLInputElement> | undefined>();
211
- expectTypeOf<ComboboxProps>().toHaveProperty('placeholder').toEqualTypeOf<string | undefined>();
212
213
  expectTypeOf<ComboboxProps>().toHaveProperty('aria-label').toEqualTypeOf<string | undefined>();
213
214
  expectTypeOf<ComboboxProps>().toHaveProperty('role').toEqualTypeOf<AriaRole | undefined>();
214
215
  expectTypeOf<ComboboxProps>().toHaveProperty('autoComplete').toEqualTypeOf<string | undefined>();
@@ -225,26 +226,54 @@ describe('Unions', () => {
225
226
  expectTypeOf<ComboboxProps>({ items: [], readOnly: true, disabled: true, alwaysOpened: true });
226
227
  });
227
228
 
228
- it('IsMultiselect', () => {
229
+ it('IsMultiple', () => {
229
230
  expectTypeOf<ComboboxProps>({ items: [], value: '' });
231
+ expectTypeOf<ComboboxProps>({ items: [], onChange: (value: string) => value });
232
+ expectTypeOf<ComboboxProps>({ items: [], multiple: false, defaultValue: '' });
230
233
  expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: [] });
231
- expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: [''] });
232
- expectTypeOf<ComboboxProps>({ items: [], multiple: true, onChange: (value: string[]) => {} });
233
- expectTypeOf<ComboboxProps>({ items: [], multiple: false, onChange: (value: string) => {} });
234
- // @ts-expect-error
235
- expectTypeOf<ComboboxProps>({ items: [], multiple: false, value: [] });
236
- // @ts-expect-error
237
- expectTypeOf<ComboboxProps>({ items: [], multiple: false, onChange: (value: string[]) => {} });
238
- // @ts-expect-error
239
- expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: '' });
240
- // @ts-expect-error
241
- expectTypeOf<ComboboxProps>({ items: [], multiple: true, onChange: (value: string) => {} });
234
+ expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: ['value'] });
235
+ expectTypeOf<ComboboxProps>({ items: [], multiple: true, defaultValue: ['value'] });
236
+ expectTypeOf<ComboboxProps>({ items: [], multiple: true, onChange: (value: string[]) => value });
242
237
  expectTypeOf<ComboboxProps>({ items: [], isTargetAmount: false });
243
238
  expectTypeOf<ComboboxProps>({ items: [], multiple: true, isTargetAmount: true });
244
239
  expectTypeOf<ComboboxProps>({ items: [], multiple: true, targetAmount: 1 });
245
240
  expectTypeOf<ComboboxProps>({ items: [], multiple: true, renderValue: () => '' });
246
- expectTypeOf<ComboboxProps>({ items: [], multiple: true, selectAllOptions: { checked: true } });
241
+ expectTypeOf<ComboboxProps>({ items: [], multiple: true, selectAllOptions: { label: 'All' } });
247
242
  expectTypeOf<ComboboxProps>({ items: [], multiple: true, chipClickArea: 'full' });
243
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country' });
244
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country', defaultValue: '', multiple: false });
245
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country', defaultValue: ['value'], multiple: true });
246
+ expectTypeOf<ComboboxProps>({
247
+ items: [],
248
+ name: 'country',
249
+ onChange: (e: React.ChangeEvent<HTMLSelectElement>) => e.target.value,
250
+ });
251
+ expectTypeOf<ComboboxProps>({
252
+ items: [],
253
+ name: 'country',
254
+ value: '',
255
+ onChange: (value: string) => value,
256
+ });
257
+ expectTypeOf<ComboboxProps>({
258
+ items: [],
259
+ name: 'country',
260
+ multiple: true,
261
+ value: ['value'],
262
+ onChange: (value: string[]) => value,
263
+ });
264
+
265
+ // @ts-expect-error
266
+ expectTypeOf<ComboboxProps>({ items: [], multiple: false, value: [] });
267
+ // @ts-expect-error
268
+ expectTypeOf<ComboboxProps>({ items: [], multiple: true, value: '' });
269
+ // @ts-expect-error
270
+ expectTypeOf<ComboboxProps>({ items: [], multiple: false, defaultValue: [] });
271
+ // @ts-expect-error
272
+ expectTypeOf<ComboboxProps>({ items: [], multiple: true, defaultValue: '' });
273
+ // @ts-expect-error
274
+ expectTypeOf<ComboboxProps>({ items: [], multiple: false, onChange: (value: string[]) => value });
275
+ // @ts-expect-error
276
+ expectTypeOf<ComboboxProps>({ items: [], multiple: true, onChange: (value: string) => value });
248
277
  // @ts-expect-error
249
278
  expectTypeOf<ComboboxProps>({ items: [], isTargetAmount: true });
250
279
  // @ts-expect-error
@@ -252,50 +281,102 @@ describe('Unions', () => {
252
281
  // @ts-expect-error
253
282
  expectTypeOf<ComboboxProps>({ items: [], renderValue: () => '' });
254
283
  // @ts-expect-error
255
- expectTypeOf<ComboboxProps>({ items: [], selectAllOptions: { checked: true } });
284
+ expectTypeOf<ComboboxProps>({ items: [], selectAllOptions: { label: 'All' } });
256
285
  // @ts-expect-error
257
286
  expectTypeOf<ComboboxProps>({ items: [], chipClickArea: 'full' });
258
- expectTypeOf<ComboboxProps>({ items: [], name: '', defaultValue: '' });
259
- expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, defaultValue: [''] });
260
287
  // @ts-expect-error
261
- expectTypeOf<ComboboxProps>({ items: [], name: '', value: '' });
262
- expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, isTargetAmount: true });
263
- expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, targetAmount: 1 });
264
- expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, renderValue: () => '' });
265
- expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, selectAllOptions: { checked: true } });
266
- expectTypeOf<ComboboxProps>({ items: [], name: '', multiple: true, chipClickArea: 'full' });
288
+ expectTypeOf<ComboboxProps>({
289
+ items: [],
290
+ name: 'country',
291
+ value: '',
292
+ onChange: (e: React.ChangeEvent<HTMLSelectElement>) => e.target.value,
293
+ });
294
+ // @ts-expect-error
295
+ expectTypeOf<ComboboxProps>({
296
+ items: [],
297
+ name: 'country',
298
+ multiple: true,
299
+ value: ['value'],
300
+ onChange: (e: React.ChangeEvent<HTMLSelectElement>) => e.target.value,
301
+ });
302
+ // @ts-expect-error
303
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country', isTargetAmount: true });
267
304
  // @ts-expect-error
268
- expectTypeOf<ComboboxProps>({ items: [], name: '', isTargetAmount: true });
305
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country', targetAmount: 1 });
269
306
  // @ts-expect-error
270
- expectTypeOf<ComboboxProps>({ items: [], name: '', targetAmount: 1 });
307
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country', renderValue: () => '' });
271
308
  // @ts-expect-error
272
- expectTypeOf<ComboboxProps>({ items: [], name: '', renderValue: () => '' });
309
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country', selectAllOptions: { label: 'All' } });
273
310
  // @ts-expect-error
274
- expectTypeOf<ComboboxProps>({ items: [], name: '', selectAllOptions: { checked: true } });
311
+ expectTypeOf<ComboboxProps>({ items: [], name: 'country', chipClickArea: 'full' });
312
+ });
313
+
314
+ it('HintProps', () => {
315
+ expectTypeOf<ComboboxProps>({ items: [], hintText: 'hint' });
316
+ expectTypeOf<ComboboxProps>({ items: [], hintText: 'hint', hintTrigger: 'hover' });
317
+ expectTypeOf<ComboboxProps>({ items: [], hintText: 'hint', hintHasArrow: true });
318
+ expectTypeOf<ComboboxProps>({ items: [], hintText: 'hint', hintOffset: [0, 8] });
319
+ expectTypeOf<ComboboxProps>({ items: [], hintText: 'hint', hintPlacement: 'top' });
320
+
321
+ // @ts-expect-error
322
+ expectTypeOf<ComboboxProps>({ items: [], hintTrigger: 'hover' });
275
323
  // @ts-expect-error
276
- expectTypeOf<ComboboxProps>({ items: [], name: '', chipClickArea: 'full' });
324
+ expectTypeOf<ComboboxProps>({ items: [], hintHasArrow: true });
325
+ // @ts-expect-error
326
+ expectTypeOf<ComboboxProps>({ items: [], hintOffset: [0, 8] });
327
+ // @ts-expect-error
328
+ expectTypeOf<ComboboxProps>({ items: [], hintPlacement: 'top' });
277
329
  });
278
330
  });
279
331
 
280
332
  describe('Generics', () => {
281
333
  it('ItemOption', () => {
282
- const items = [{ value: '', label: '', randomProp: '', boolProp: true }];
334
+ const items = [{ value: '1', label: 'One', customLabel: 'Custom', isAvailable: true }];
335
+
336
+ void (
337
+ <Combobox
338
+ items={items}
339
+ onChange={(_, item) => item?.customLabel}
340
+ renderItem={(item) => item?.customLabel}
341
+ filter={(item) => item.isAvailable}
342
+ />
343
+ );
344
+
345
+ void (
346
+ <Combobox
347
+ multiple
348
+ items={items}
349
+ onChange={(_, item) => item?.customLabel}
350
+ renderItem={(item) => item?.customLabel}
351
+ renderValue={(item) => item?.customLabel}
352
+ filter={(item) => item.isAvailable}
353
+ />
354
+ );
355
+
356
+ void (
357
+ <Combobox
358
+ items={items}
359
+ // @ts-expect-error
360
+ renderItem={(item) => item?.nonExistedProp}
361
+ // @ts-expect-error
362
+ filter={(item) => item.nonExistedProp}
363
+ // @ts-expect-error
364
+ onChange={(_, item) => item?.nonExistedProp}
365
+ />
366
+ );
283
367
 
284
- void (<Combobox items={items} />);
285
368
  void (
286
369
  <Combobox
287
370
  multiple
288
371
  items={items}
289
- renderItem={(item) => {
290
- return item.randomProp;
291
- }}
292
- filter={(item) => item.boolProp}
293
- onChange={(value: string[], item) => {
294
- return item && item.randomProp;
295
- }}
296
- renderValue={(item) => {
297
- return item.randomProp;
298
- }}
372
+ // @ts-expect-error
373
+ renderItem={(item) => item?.nonExistedProp}
374
+ // @ts-expect-error
375
+ renderValue={(item) => item?.nonExistedProp}
376
+ // @ts-expect-error
377
+ filter={(item) => item.nonExistedProp}
378
+ // @ts-expect-error
379
+ onChange={(_, item) => item?.nonExistedProp}
299
380
  />
300
381
  );
301
382
  });
@@ -326,7 +407,7 @@ describe('Examples', () => {
326
407
 
327
408
  it('Single', () => {
328
409
  () => {
329
- const [value, setValue] = useState<string>('');
410
+ const [value, setValue] = useState('');
330
411
 
331
412
  return (
332
413
  <Combobox
@@ -377,42 +458,184 @@ describe('Examples', () => {
377
458
  };
378
459
  });
379
460
 
380
- it('Portal', () => {
461
+ it('RenderValue', () => {
381
462
  () => {
382
- const [value, setValue] = useState<string>('');
383
-
384
- const ref = useRef(null);
463
+ const [value, setValue] = useState<string[]>(['brazil']);
464
+ const renderValue = (item: ItemOption) => `${item.value} - ${item.label}`;
385
465
 
386
466
  return (
387
467
  <Combobox
468
+ multiple
388
469
  items={items}
470
+ label="Label"
471
+ placeholder="Placeholder"
389
472
  value={value}
390
473
  onChange={setValue}
474
+ renderValue={renderValue}
475
+ />
476
+ );
477
+ };
478
+ });
479
+
480
+ it('RenderItem', () => {
481
+ () => {
482
+ const [value, setValue] = useState<string[]>([]);
483
+ const renderItem = ({ label }: ItemOption) => (
484
+ <Cell
485
+ view="default"
486
+ title={label}
487
+ label="Top left"
488
+ contentRight={<Cell view="default" title="Bottom right" label="Top right" />}
489
+ />
490
+ );
491
+
492
+ return (
493
+ <Combobox
494
+ multiple
391
495
  placeholder="Placeholder"
392
- label="Label"
393
- helperText="Helper text"
394
- portal={ref}
395
- listWidth="300px"
496
+ items={items}
497
+ value={value}
498
+ onChange={setValue}
499
+ renderItem={renderItem}
396
500
  />
397
501
  );
398
502
  };
399
503
  });
400
504
 
401
- it('Uncontrolled', () => {
505
+ it('RenderSelectionIcon', () => {
506
+ () => {
507
+ const [value, setValue] = useState('brazil');
508
+
509
+ const renderSelectionIcon = (selected: boolean | 'indeterminate') => {
510
+ if (selected === true) {
511
+ return <div />;
512
+ }
513
+
514
+ if (selected === 'indeterminate') {
515
+ return <span />;
516
+ }
517
+
518
+ return null;
519
+ };
520
+
521
+ return (
522
+ <Combobox items={items} value={value} onChange={setValue} renderSelectionIcon={renderSelectionIcon} />
523
+ );
524
+ };
525
+ });
526
+
527
+ it('Portal', () => {
402
528
  () => {
403
- return <Combobox items={items} placeholder="Placeholder" label="Label" helperText="Helper text" />;
529
+ const [value, setValue] = useState('');
530
+ const ref = useRef<HTMLDivElement>(null);
531
+
532
+ return (
533
+ <div ref={ref}>
534
+ <Combobox
535
+ items={items}
536
+ value={value}
537
+ onChange={setValue}
538
+ placeholder="Placeholder"
539
+ label="Label"
540
+ helperText="Helper text"
541
+ portal={ref}
542
+ listWidth="300px"
543
+ />
544
+ </div>
545
+ );
404
546
  };
405
547
  });
406
548
 
407
549
  it('Uncontrolled', () => {
408
550
  () => {
409
- const items = Array(5000)
551
+ return (
552
+ <>
553
+ <Combobox items={items} placeholder="Placeholder" label="Label" helperText="Helper text" />
554
+
555
+ <Combobox
556
+ items={items}
557
+ defaultValue="north_america"
558
+ label="Label"
559
+ placeholder="Placeholder"
560
+ onChange={(value, item) => item?.value || value}
561
+ />
562
+
563
+ <Combobox
564
+ multiple
565
+ items={items}
566
+ defaultValue={['north_america']}
567
+ label="Label"
568
+ placeholder="Placeholder"
569
+ onChange={(value, item) => item?.value || value.join(',')}
570
+ />
571
+ </>
572
+ );
573
+ };
574
+ });
575
+
576
+ it('react-hook-form register', () => {
577
+ () => {
578
+ const { register: registerSingle } = useForm<{ region: string }>({
579
+ defaultValues: {
580
+ region: 'north_america',
581
+ },
582
+ });
583
+ const { register: registerMultiple } = useForm<{ region: string[] }>({
584
+ defaultValues: {
585
+ region: ['north_america'],
586
+ },
587
+ });
588
+
589
+ return (
590
+ <>
591
+ <Combobox items={items} {...registerSingle('region')} />
592
+
593
+ <Combobox multiple items={items} {...registerMultiple('region')} />
594
+ </>
595
+ );
596
+ };
597
+ });
598
+
599
+ it('react-hook-form Controller', () => {
600
+ () => {
601
+ const { control: singleControl } = useForm<{ region: string }>({
602
+ defaultValues: {
603
+ region: 'north_america',
604
+ },
605
+ });
606
+ const { control: multipleControl } = useForm<{ region: string[] }>({
607
+ defaultValues: {
608
+ region: ['north_america'],
609
+ },
610
+ });
611
+
612
+ return (
613
+ <>
614
+ <Controller
615
+ name="region"
616
+ control={singleControl}
617
+ render={({ field }) => <Combobox items={items} {...field} />}
618
+ />
619
+
620
+ <Controller
621
+ name="region"
622
+ control={multipleControl}
623
+ render={({ field }) => <Combobox multiple items={items} {...field} />}
624
+ />
625
+ </>
626
+ );
627
+ };
628
+ });
629
+
630
+ it('Virtual', () => {
631
+ () => {
632
+ const virtualItems = Array(5000)
410
633
  .fill(1)
411
634
  .map((_, i) => ({ value: i.toString(), label: i.toString() }));
412
635
 
413
636
  return (
414
637
  <Combobox
415
- items={items}
638
+ items={virtualItems}
416
639
  virtual
417
640
  listMaxHeight="200px"
418
641
  placeholder="Placeholder"
@@ -423,18 +646,53 @@ describe('Examples', () => {
423
646
  };
424
647
  });
425
648
 
426
- it('Disabled elements', () => {
649
+ it('Infinite loading', () => {
427
650
  () => {
428
- const [value, setValue] = useState(['brazil']);
651
+ const [infiniteItems, setInfiniteItems] = useState(items);
652
+ const [isInfiniteLoading, setIsInfiniteLoading] = useState(false);
653
+
654
+ const handleScroll = async (e: React.UIEvent<HTMLElement>) => {
655
+ if (isInfiniteLoading) return;
656
+
657
+ if (e.currentTarget.scrollTop + e.currentTarget.offsetHeight + 10 > e.currentTarget.scrollHeight) {
658
+ setIsInfiniteLoading(true);
659
+ setInfiniteItems((prev) => [...prev, ...items]);
660
+ setIsInfiniteLoading(false);
661
+ }
662
+ };
429
663
 
430
664
  return (
431
665
  <Combobox
432
- multiple
433
- label="Label"
666
+ items={infiniteItems}
667
+ listMaxHeight="200px"
434
668
  placeholder="Placeholder"
669
+ label="Label"
670
+ helperText="Helper text"
671
+ onScroll={handleScroll}
672
+ afterList={isInfiniteLoading ? <center>Загружаю...</center> : undefined}
673
+ />
674
+ );
675
+ };
676
+ });
677
+
678
+ it('SelectAll', () => {
679
+ () => {
680
+ const [value, setValue] = useState<string[]>([]);
681
+
682
+ return (
683
+ <Combobox
684
+ multiple
435
685
  items={items}
436
686
  value={value}
437
687
  onChange={setValue}
688
+ label="Multiple"
689
+ placeholder="Placeholder"
690
+ selectAllOptions={{
691
+ checked: value.length === items.length,
692
+ indeterminate: value.length > 0 && value.length < items.length,
693
+ label: 'Выбрать все',
694
+ sticky: true,
695
+ }}
438
696
  isTargetAmount
439
697
  />
440
698
  );