@snack-uikit/search 0.4.13-preview-85c5f47b.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/CHANGELOG.md +301 -0
- package/LICENSE +201 -0
- package/README.md +74 -0
- package/dist/components/Search/Search.d.ts +22 -0
- package/dist/components/Search/Search.js +28 -0
- package/dist/components/Search/index.d.ts +1 -0
- package/dist/components/Search/index.js +1 -0
- package/dist/components/SearchAutocomplete/SearchAutocomplete.d.ts +23 -0
- package/dist/components/SearchAutocomplete/SearchAutocomplete.js +53 -0
- package/dist/components/SearchAutocomplete/index.d.ts +1 -0
- package/dist/components/SearchAutocomplete/index.js +1 -0
- package/dist/components/SearchAutocomplete/styles.module.css +9 -0
- package/dist/components/SearchDecorator/SearchDecorator.d.ts +13 -0
- package/dist/components/SearchDecorator/SearchDecorator.js +21 -0
- package/dist/components/SearchDecorator/index.d.ts +1 -0
- package/dist/components/SearchDecorator/index.js +1 -0
- package/dist/components/SearchDecorator/styles.module.css +45 -0
- package/dist/components/SearchFieldText/SearchFieldText.d.ts +10 -0
- package/dist/components/SearchFieldText/SearchFieldText.js +20 -0
- package/dist/components/SearchFieldText/index.d.ts +1 -0
- package/dist/components/SearchFieldText/index.js +1 -0
- package/dist/components/SearchPrivate/SearchPrivate.d.ts +28 -0
- package/dist/components/SearchPrivate/SearchPrivate.js +63 -0
- package/dist/components/SearchPrivate/index.d.ts +1 -0
- package/dist/components/SearchPrivate/index.js +1 -0
- package/dist/components/SearchPrivate/styles.module.css +68 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/constants.d.ts +18 -0
- package/dist/constants.js +19 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +48 -0
- package/src/components/Search/Search.tsx +75 -0
- package/src/components/Search/index.ts +1 -0
- package/src/components/SearchAutocomplete/SearchAutocomplete.tsx +128 -0
- package/src/components/SearchAutocomplete/index.ts +1 -0
- package/src/components/SearchAutocomplete/styles.module.scss +13 -0
- package/src/components/SearchDecorator/SearchDecorator.tsx +39 -0
- package/src/components/SearchDecorator/index.ts +1 -0
- package/src/components/SearchDecorator/styles.module.scss +41 -0
- package/src/components/SearchFieldText/SearchFieldText.tsx +32 -0
- package/src/components/SearchFieldText/index.ts +1 -0
- package/src/components/SearchPrivate/SearchPrivate.tsx +130 -0
- package/src/components/SearchPrivate/index.ts +1 -0
- package/src/components/SearchPrivate/styles.module.scss +43 -0
- package/src/components/index.ts +2 -0
- package/src/constants.ts +20 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
2
|
+
import mergeRefs from 'merge-refs';
|
|
3
|
+
import { forwardRef, KeyboardEvent, useCallback, useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { Droplist, ItemSingleProps } from '@snack-uikit/droplist';
|
|
6
|
+
|
|
7
|
+
import { PRIVATE_SEARCH_TEST_IDS, Size, TEST_IDS } from '../../constants';
|
|
8
|
+
import { SearchDecorator } from '../SearchDecorator';
|
|
9
|
+
import { SearchPrivate, SearchPrivateProps } from '../SearchPrivate';
|
|
10
|
+
import styles from './styles.module.scss';
|
|
11
|
+
|
|
12
|
+
export type SearchAutocompleteProps = Omit<SearchPrivateProps, 'onKeyDown'> & {
|
|
13
|
+
/**
|
|
14
|
+
* Элементы выпадающие в Droplist в режиме Autocomplete.
|
|
15
|
+
*
|
|
16
|
+
* На нажатие 'Space', 'Enter' или клике по элементу будет вызываться onSubmit.
|
|
17
|
+
*/
|
|
18
|
+
options: Pick<ItemSingleProps, 'option' | 'description' | 'tagLabel' | 'icon' | 'caption' | 'avatar'>[];
|
|
19
|
+
/** Внешний бордер */
|
|
20
|
+
outline?: boolean;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const SearchAutocomplete = forwardRef<HTMLInputElement, SearchAutocompleteProps>(function SearchAutocomplete(
|
|
24
|
+
{
|
|
25
|
+
size = Size.S,
|
|
26
|
+
value,
|
|
27
|
+
onChange,
|
|
28
|
+
placeholder,
|
|
29
|
+
options = [],
|
|
30
|
+
loading,
|
|
31
|
+
outline,
|
|
32
|
+
onSubmit,
|
|
33
|
+
onFocus,
|
|
34
|
+
className,
|
|
35
|
+
...rest
|
|
36
|
+
},
|
|
37
|
+
ref,
|
|
38
|
+
) {
|
|
39
|
+
const scrollRef = useRef<HTMLElement>(null);
|
|
40
|
+
|
|
41
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
42
|
+
|
|
43
|
+
const {
|
|
44
|
+
firstElementRefCallback,
|
|
45
|
+
handleDroplistFocusLeave,
|
|
46
|
+
handleDroplistItemClick,
|
|
47
|
+
handleTriggerKeyDown,
|
|
48
|
+
handleDroplistItemKeyDown,
|
|
49
|
+
triggerElementRef,
|
|
50
|
+
} = Droplist.useKeyboardNavigation<HTMLInputElement>({
|
|
51
|
+
setDroplistOpen: setIsOpen,
|
|
52
|
+
triggerType: Droplist.useKeyboardNavigation.triggerTypes.Input,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const handleOptionKeyDown = useCallback(
|
|
56
|
+
(event: KeyboardEvent<HTMLButtonElement>) => {
|
|
57
|
+
event.stopPropagation();
|
|
58
|
+
|
|
59
|
+
// ignoring special keys (tab, arrows, backspace and etc.)
|
|
60
|
+
if (event.key.length === 1) {
|
|
61
|
+
triggerElementRef.current?.focus();
|
|
62
|
+
scrollRef.current?.scroll(0, 0);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
[triggerElementRef, scrollRef],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
69
|
+
handleTriggerKeyDown(e);
|
|
70
|
+
|
|
71
|
+
if (e.key.length === 1) {
|
|
72
|
+
setIsOpen(true);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div className={cn(styles.wrap, className)} {...rest}>
|
|
78
|
+
<Droplist
|
|
79
|
+
open={Boolean(triggerElementRef.current?.value) && isOpen && options.length > 0}
|
|
80
|
+
firstElementRefCallback={firstElementRefCallback}
|
|
81
|
+
useScroll
|
|
82
|
+
size={size}
|
|
83
|
+
onFocusLeave={handleDroplistFocusLeave}
|
|
84
|
+
onOpenChange={setIsOpen}
|
|
85
|
+
data-test-id={TEST_IDS.droplist}
|
|
86
|
+
triggerClassName={styles.triggerClassName}
|
|
87
|
+
scrollRef={scrollRef}
|
|
88
|
+
triggerRef={triggerElementRef}
|
|
89
|
+
triggerElement={
|
|
90
|
+
<SearchDecorator
|
|
91
|
+
size={size}
|
|
92
|
+
outline={outline || undefined}
|
|
93
|
+
focused={(isOpen && Boolean(triggerElementRef.current?.value)) || undefined}
|
|
94
|
+
data-test-id={TEST_IDS.decorator}
|
|
95
|
+
>
|
|
96
|
+
<SearchPrivate
|
|
97
|
+
loading={loading}
|
|
98
|
+
value={value}
|
|
99
|
+
onChange={onChange}
|
|
100
|
+
onSubmit={onSubmit}
|
|
101
|
+
placeholder={placeholder}
|
|
102
|
+
ref={mergeRefs(ref, triggerElementRef)}
|
|
103
|
+
onKeyDown={onKeyDown}
|
|
104
|
+
onFocus={onFocus}
|
|
105
|
+
size={size}
|
|
106
|
+
data-test-id={PRIVATE_SEARCH_TEST_IDS.field}
|
|
107
|
+
/>
|
|
108
|
+
</SearchDecorator>
|
|
109
|
+
}
|
|
110
|
+
>
|
|
111
|
+
{options.map(item => (
|
|
112
|
+
<Droplist.ItemSingle
|
|
113
|
+
{...item}
|
|
114
|
+
key={item.option}
|
|
115
|
+
onClick={e => {
|
|
116
|
+
handleDroplistItemClick(e);
|
|
117
|
+
onChange?.(item.option);
|
|
118
|
+
onSubmit?.(item.option);
|
|
119
|
+
triggerElementRef.current?.blur();
|
|
120
|
+
}}
|
|
121
|
+
onKeyDown={e => handleDroplistItemKeyDown(e, handleOptionKeyDown)}
|
|
122
|
+
data-test-id={TEST_IDS.option}
|
|
123
|
+
/>
|
|
124
|
+
))}
|
|
125
|
+
</Droplist>
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SearchAutocomplete';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
|
|
5
|
+
|
|
6
|
+
import { Size } from '../../constants';
|
|
7
|
+
import { SearchProps } from '../Search';
|
|
8
|
+
import styles from './styles.module.scss';
|
|
9
|
+
|
|
10
|
+
export type SearchDecoratorProps = WithSupportProps<
|
|
11
|
+
{
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
focused?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
} & Pick<SearchProps, 'outline' | 'size'>
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
export function SearchDecorator({
|
|
19
|
+
children,
|
|
20
|
+
outline,
|
|
21
|
+
size = Size.S,
|
|
22
|
+
focused,
|
|
23
|
+
className,
|
|
24
|
+
...rest
|
|
25
|
+
}: SearchDecoratorProps) {
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
className={cn(styles.decorator, className)}
|
|
29
|
+
data-outline={outline || undefined}
|
|
30
|
+
data-size={size}
|
|
31
|
+
data-focused={focused || undefined}
|
|
32
|
+
{...extractSupportProps(rest)}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
SearchDecorator.sizes = Size;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SearchDecorator';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
@import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-search';
|
|
2
|
+
@import "@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element";
|
|
3
|
+
|
|
4
|
+
$sizes: 's', 'm', 'l';
|
|
5
|
+
|
|
6
|
+
.decorator {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex: 1 0 auto;
|
|
9
|
+
align-items: center;
|
|
10
|
+
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
|
|
13
|
+
background-color: $sys-neutral-background1-level;
|
|
14
|
+
border-color: transparent;
|
|
15
|
+
border-style: solid;
|
|
16
|
+
|
|
17
|
+
@each $size in $sizes {
|
|
18
|
+
&[data-size='#{$size}'] {
|
|
19
|
+
@include composite-var($search, $size);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&[data-outline] {
|
|
24
|
+
border-color: $sys-neutral-decor-default;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:hover {
|
|
28
|
+
background-color: $sys-neutral-background2-level;
|
|
29
|
+
border-color: $sys-primary-decor-hovered;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&:focus-within,
|
|
33
|
+
&[data-focused] {
|
|
34
|
+
@include outline-var($container-focused-m);
|
|
35
|
+
|
|
36
|
+
background-color: $sys-neutral-background2-level;
|
|
37
|
+
border-color: $sys-primary-accent-default;
|
|
38
|
+
outline-color: $sys-primary-decor-activated;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import { PRIVATE_SEARCH_TEST_IDS, Size } from '../../constants';
|
|
4
|
+
import { SearchDecorator } from '../SearchDecorator';
|
|
5
|
+
import { SearchPrivate, SearchPrivateProps } from '../SearchPrivate';
|
|
6
|
+
|
|
7
|
+
export type SearchTextFieldProps = Omit<SearchPrivateProps, 'onKeyDown'> & {
|
|
8
|
+
/** Внешний бордер */
|
|
9
|
+
outline?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const SearchFieldText = forwardRef<HTMLInputElement, SearchTextFieldProps>(function SearchFieldText(
|
|
13
|
+
{ value, onChange, onBlur, onFocus, size = Size.S, outline, loading, placeholder, onSubmit, className, ...rest },
|
|
14
|
+
ref,
|
|
15
|
+
) {
|
|
16
|
+
return (
|
|
17
|
+
<SearchDecorator outline={outline} size={size} className={className} {...rest}>
|
|
18
|
+
<SearchPrivate
|
|
19
|
+
ref={ref}
|
|
20
|
+
size={size}
|
|
21
|
+
value={value}
|
|
22
|
+
onChange={onChange}
|
|
23
|
+
onBlur={onBlur}
|
|
24
|
+
onFocus={onFocus}
|
|
25
|
+
onSubmit={onSubmit}
|
|
26
|
+
placeholder={placeholder}
|
|
27
|
+
loading={loading}
|
|
28
|
+
data-test-id={PRIVATE_SEARCH_TEST_IDS.field}
|
|
29
|
+
/>
|
|
30
|
+
</SearchDecorator>
|
|
31
|
+
);
|
|
32
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SearchFieldText';
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
2
|
+
import mergeRefs from 'merge-refs';
|
|
3
|
+
import { FocusEvent, forwardRef, KeyboardEvent, useCallback, useMemo, useRef } from 'react';
|
|
4
|
+
import { useUncontrolledProp } from 'uncontrollable';
|
|
5
|
+
|
|
6
|
+
import { SearchSVG } from '@snack-uikit/icons';
|
|
7
|
+
import {
|
|
8
|
+
InputPrivate,
|
|
9
|
+
InputPrivateProps,
|
|
10
|
+
moveCursorToEnd,
|
|
11
|
+
useButtonNavigation,
|
|
12
|
+
useClearButton,
|
|
13
|
+
} from '@snack-uikit/input-private';
|
|
14
|
+
import { Sun } from '@snack-uikit/loaders';
|
|
15
|
+
import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
|
|
16
|
+
|
|
17
|
+
import { PRIVATE_SEARCH_TEST_IDS, Size } from '../../constants';
|
|
18
|
+
import styles from './styles.module.scss';
|
|
19
|
+
|
|
20
|
+
export type SearchPrivateProps = WithSupportProps<
|
|
21
|
+
{
|
|
22
|
+
/** Размер */
|
|
23
|
+
size?: Size;
|
|
24
|
+
/** Состояние загрузки */
|
|
25
|
+
loading?: boolean;
|
|
26
|
+
/** Колбек на подтверждение поиска по строке */
|
|
27
|
+
onSubmit?(value: string): void;
|
|
28
|
+
/** CSS-класс */
|
|
29
|
+
className?: string;
|
|
30
|
+
} & Pick<Partial<InputPrivateProps>, 'value' | 'onChange' | 'placeholder' | 'onFocus' | 'onBlur' | 'onKeyDown'>
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
const SearchPrivateComponent = forwardRef<HTMLInputElement, SearchPrivateProps>(function SearchPrivate(
|
|
34
|
+
{
|
|
35
|
+
size = Size.S,
|
|
36
|
+
value: valueProp = '',
|
|
37
|
+
onChange: onChangeProp,
|
|
38
|
+
loading,
|
|
39
|
+
placeholder,
|
|
40
|
+
onKeyDown,
|
|
41
|
+
onFocus,
|
|
42
|
+
onBlur,
|
|
43
|
+
onSubmit,
|
|
44
|
+
className,
|
|
45
|
+
...rest
|
|
46
|
+
},
|
|
47
|
+
ref,
|
|
48
|
+
) {
|
|
49
|
+
const [value, onValueChange] = useUncontrolledProp(valueProp, '', onChangeProp);
|
|
50
|
+
|
|
51
|
+
const localRef = useRef<HTMLInputElement>(null);
|
|
52
|
+
const clearButtonRef = useRef<HTMLButtonElement>(null);
|
|
53
|
+
|
|
54
|
+
const showClearButton = Boolean(value);
|
|
55
|
+
|
|
56
|
+
const onClear = () => {
|
|
57
|
+
onValueChange('');
|
|
58
|
+
|
|
59
|
+
localRef.current?.focus();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const clearButtonSettings = useClearButton({
|
|
63
|
+
clearButtonRef,
|
|
64
|
+
showClearButton,
|
|
65
|
+
size,
|
|
66
|
+
onClear,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const { buttons, inputTabIndex, onInputKeyDown } = useButtonNavigation({
|
|
70
|
+
inputRef: localRef,
|
|
71
|
+
buttons: useMemo(() => [clearButtonSettings], [clearButtonSettings]),
|
|
72
|
+
readonly: false,
|
|
73
|
+
submitKeys: ['Enter', 'Space'],
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const handleKeyDown = useCallback(
|
|
77
|
+
(e: KeyboardEvent<HTMLInputElement>) => {
|
|
78
|
+
onKeyDown && onKeyDown(e);
|
|
79
|
+
onInputKeyDown(e);
|
|
80
|
+
|
|
81
|
+
if (e.key === 'Enter' && localRef.current?.value) {
|
|
82
|
+
onSubmit && onSubmit(localRef.current.value);
|
|
83
|
+
// TODO: think about remove blur behavior
|
|
84
|
+
localRef.current?.blur();
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
[onInputKeyDown, onKeyDown, onSubmit],
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const handleOnFocus = useCallback(
|
|
91
|
+
(e: FocusEvent<HTMLInputElement, Element>) => {
|
|
92
|
+
onFocus && onFocus(e);
|
|
93
|
+
moveCursorToEnd(localRef.current);
|
|
94
|
+
},
|
|
95
|
+
[onFocus],
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<div className={cn(styles.container, className)} {...extractSupportProps(rest)} data-size={size}>
|
|
100
|
+
<span className={styles.prefix}>
|
|
101
|
+
{loading ? (
|
|
102
|
+
<Sun data-test-id={PRIVATE_SEARCH_TEST_IDS.iconSun} />
|
|
103
|
+
) : (
|
|
104
|
+
<SearchSVG data-test-id={PRIVATE_SEARCH_TEST_IDS.iconSearch} />
|
|
105
|
+
)}
|
|
106
|
+
</span>
|
|
107
|
+
|
|
108
|
+
<InputPrivate
|
|
109
|
+
value={value}
|
|
110
|
+
onChange={onValueChange}
|
|
111
|
+
onKeyDown={handleKeyDown}
|
|
112
|
+
onFocus={handleOnFocus}
|
|
113
|
+
onBlur={onBlur}
|
|
114
|
+
tabIndex={inputTabIndex}
|
|
115
|
+
ref={mergeRefs(ref, localRef)}
|
|
116
|
+
placeholder={placeholder}
|
|
117
|
+
type={InputPrivate.types.Text}
|
|
118
|
+
data-test-id={PRIVATE_SEARCH_TEST_IDS.input}
|
|
119
|
+
/>
|
|
120
|
+
|
|
121
|
+
<span className={styles.postfix}>{buttons}</span>
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export const SearchPrivate = SearchPrivateComponent as typeof SearchPrivateComponent & {
|
|
127
|
+
sizes: typeof Size;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
SearchPrivate.sizes = Size;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SearchPrivate';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
@import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-search';
|
|
2
|
+
@import "@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element";
|
|
3
|
+
|
|
4
|
+
$sizes: 's', 'm', 'l';
|
|
5
|
+
|
|
6
|
+
.container {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-grow: 1;
|
|
9
|
+
align-items: center;
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
|
|
12
|
+
@each $size in $sizes {
|
|
13
|
+
&[data-size='#{$size}'] {
|
|
14
|
+
@include composite-var($search-private, $size);
|
|
15
|
+
|
|
16
|
+
input {
|
|
17
|
+
@include composite-var($theme-variables, 'sans', 'body', $size);
|
|
18
|
+
|
|
19
|
+
cursor: text;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
svg {
|
|
23
|
+
width: $icon-s !important; /* stylelint-disable-line declaration-no-important */
|
|
24
|
+
height: $icon-s !important; /* stylelint-disable-line declaration-no-important */
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.prefix {
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
flex-shrink: 0;
|
|
33
|
+
align-items: center;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
|
|
36
|
+
color: $sys-neutral-text-light;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.postfix {
|
|
40
|
+
display: inline-flex;
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
gap: $space-fields-postfix-gap;
|
|
43
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export enum Size {
|
|
2
|
+
S = 's',
|
|
3
|
+
M = 'm',
|
|
4
|
+
L = 'l',
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const TEST_IDS = {
|
|
8
|
+
main: 'search',
|
|
9
|
+
decorator: 'search__decorator',
|
|
10
|
+
droplist: 'search__droplist',
|
|
11
|
+
option: 'search__option',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const PRIVATE_SEARCH_TEST_IDS = {
|
|
15
|
+
field: 'search__field',
|
|
16
|
+
input: 'search__field-input',
|
|
17
|
+
iconSun: 'search__icon-sun',
|
|
18
|
+
iconSearch: 'search__icon-search',
|
|
19
|
+
buttonClearValue: 'button-clear-value',
|
|
20
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|