@cloud-ru/uikit-product-mobile-fields 0.11.24

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.
Files changed (65) hide show
  1. package/CHANGELOG.md +1300 -0
  2. package/LICENSE +201 -0
  3. package/README.md +8 -0
  4. package/package.json +66 -0
  5. package/src/components/AdaptiveField/AdaptiveField.tsx +88 -0
  6. package/src/components/AdaptiveField/index.ts +1 -0
  7. package/src/components/MobileFieldDate/MobileFieldDate.tsx +375 -0
  8. package/src/components/MobileFieldDate/constants.ts +33 -0
  9. package/src/components/MobileFieldDate/index.ts +2 -0
  10. package/src/components/MobileFieldDate/styles.module.scss +75 -0
  11. package/src/components/MobileFieldDate/types.ts +6 -0
  12. package/src/components/MobileFieldDate/utils.ts +49 -0
  13. package/src/components/MobileFieldSelect/MobileFieldSelect.tsx +18 -0
  14. package/src/components/MobileFieldSelect/MobileFieldSelectMultiple.tsx +331 -0
  15. package/src/components/MobileFieldSelect/MobileFieldSelectSingle.tsx +300 -0
  16. package/src/components/MobileFieldSelect/hooks.tsx +195 -0
  17. package/src/components/MobileFieldSelect/index.ts +13 -0
  18. package/src/components/MobileFieldSelect/legacy/components/Items/hooks.tsx +53 -0
  19. package/src/components/MobileFieldSelect/legacy/components/index.ts +1 -0
  20. package/src/components/MobileFieldSelect/legacy/hooks.ts +38 -0
  21. package/src/components/MobileFieldSelect/legacy/index.ts +3 -0
  22. package/src/components/MobileFieldSelect/legacy/utils.ts +176 -0
  23. package/src/components/MobileFieldSelect/styles.module.scss +176 -0
  24. package/src/components/MobileFieldSelect/types.ts +156 -0
  25. package/src/components/MobileFieldSelect/utils/extractFieldDecoratorProps.ts +35 -0
  26. package/src/components/MobileFieldSelect/utils/extractListProps.ts +30 -0
  27. package/src/components/MobileFieldSelect/utils/getArrowIcon.ts +15 -0
  28. package/src/components/MobileFieldSelect/utils/index.ts +6 -0
  29. package/src/components/MobileFieldSelect/utils/options.tsx +88 -0
  30. package/src/components/MobileFieldSelect/utils/typeGuards.ts +38 -0
  31. package/src/components/MobileFieldSelect/utils/updateItems.ts +121 -0
  32. package/src/components/index.ts +3 -0
  33. package/src/constants/allFields.ts +11 -0
  34. package/src/constants/dateFields.ts +127 -0
  35. package/src/constants/index.ts +2 -0
  36. package/src/helperComponents/ButtonCopyValue/ButtonCopyValue.tsx +79 -0
  37. package/src/helperComponents/ButtonCopyValue/helpers.tsx +19 -0
  38. package/src/helperComponents/ButtonCopyValue/index.ts +1 -0
  39. package/src/helperComponents/ButtonCopyValue/styles.module.scss +5 -0
  40. package/src/helperComponents/FieldContainerPrivate/FieldContainerPrivate.tsx +79 -0
  41. package/src/helperComponents/FieldContainerPrivate/index.ts +1 -0
  42. package/src/helperComponents/FieldContainerPrivate/styles.module.scss +131 -0
  43. package/src/helperComponents/ItemContent/ItemContent.tsx +37 -0
  44. package/src/helperComponents/ItemContent/index.ts +1 -0
  45. package/src/helperComponents/ItemContent/styles.module.scss +80 -0
  46. package/src/helperComponents/index.ts +3 -0
  47. package/src/hooks/dateHandlers/index.ts +3 -0
  48. package/src/hooks/dateHandlers/useDateField.ts +275 -0
  49. package/src/hooks/dateHandlers/useDateFieldHelpersForMode.ts +145 -0
  50. package/src/hooks/dateHandlers/useFocusHandlers.ts +46 -0
  51. package/src/hooks/dateHandlers/useHandlers.ts +15 -0
  52. package/src/hooks/index.ts +5 -0
  53. package/src/hooks/styles.module.scss +17 -0
  54. package/src/hooks/useCopyButton.tsx +47 -0
  55. package/src/hooks/usePostfix.tsx +21 -0
  56. package/src/hooks/usePrefix.tsx +21 -0
  57. package/src/hooks/useValueControl.ts +15 -0
  58. package/src/index.ts +3 -0
  59. package/src/styles.module.scss +55 -0
  60. package/src/types/allFields.ts +9 -0
  61. package/src/types/dateFields.ts +14 -0
  62. package/src/types/index.ts +2 -0
  63. package/src/utils/adaptiveField.tsx +19 -0
  64. package/src/utils/dateFields.ts +75 -0
  65. package/src/utils/getValidationState.ts +6 -0
@@ -0,0 +1,195 @@
1
+ import { KeyboardEvent, KeyboardEventHandler, MouseEvent, RefObject, useCallback, useMemo, useRef } from 'react';
2
+ import { Handler } from 'uncontrollable';
3
+
4
+ import { BUTTON_SIZE_MAP, ButtonProps, Size, useButtonNavigation, useClearButton } from '@snack-uikit/input-private';
5
+ import { isAccordionItemProps, isNextListItemProps, SelectionSingleValueType } from '@snack-uikit/list';
6
+ import { useValueControl } from '@snack-uikit/utils';
7
+
8
+ import { ButtonCopyValue } from '../../helperComponents';
9
+ import { AsyncValueRequest } from '../../types';
10
+ import { extractChildIds } from './legacy';
11
+ import { ItemWithId, SearchState, SelectedOptionFormatter } from './types';
12
+ import { isBaseOptionProps } from './utils';
13
+
14
+ type UseHandleOnKeyDownProps = {
15
+ inputKeyDownNavigationHandler: KeyboardEventHandler<HTMLInputElement>;
16
+ onInputKeyDownProp: KeyboardEventHandler<HTMLInputElement> | undefined;
17
+ setOpen(open: boolean): void;
18
+ };
19
+
20
+ export function useHandleOnKeyDown({
21
+ setOpen,
22
+ inputKeyDownNavigationHandler,
23
+ onInputKeyDownProp,
24
+ }: UseHandleOnKeyDownProps) {
25
+ return useCallback(
26
+ (onKeyDown?: KeyboardEventHandler<HTMLElement>) => (e: KeyboardEvent<HTMLInputElement>) => {
27
+ if (e.code === 'Space') {
28
+ e.stopPropagation();
29
+ } else {
30
+ onKeyDown?.(e);
31
+ }
32
+
33
+ if (e.code === 'ArrowUp') {
34
+ setOpen(false);
35
+ }
36
+
37
+ if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
38
+ e.preventDefault();
39
+ }
40
+
41
+ if (e.key === 'Tab') {
42
+ setOpen(false);
43
+ }
44
+
45
+ inputKeyDownNavigationHandler(e);
46
+ onInputKeyDownProp?.(e);
47
+ },
48
+ [inputKeyDownNavigationHandler, onInputKeyDownProp, setOpen],
49
+ );
50
+ }
51
+
52
+ type UseCopyButtonProps = {
53
+ copyButtonRef: RefObject<HTMLButtonElement>;
54
+ showCopyButton: boolean;
55
+ valueToCopy: string;
56
+ size: Size;
57
+ onValueRequest?(): AsyncValueRequest;
58
+ disabled?: boolean;
59
+ prefix?: string;
60
+ postfix?: string;
61
+ };
62
+
63
+ export function useCopyButton({
64
+ copyButtonRef,
65
+ showCopyButton,
66
+ size,
67
+ valueToCopy,
68
+ onValueRequest,
69
+ disabled,
70
+ prefix = '',
71
+ postfix = '',
72
+ }: UseCopyButtonProps): ButtonProps {
73
+ return useMemo(
74
+ () => ({
75
+ id: 'copy',
76
+ active: true,
77
+ ref: copyButtonRef,
78
+ show: showCopyButton,
79
+ render: props => (
80
+ <ButtonCopyValue
81
+ {...props}
82
+ size={BUTTON_SIZE_MAP[size]}
83
+ valueToCopy={(prefix ?? '') + valueToCopy + (postfix ?? '')}
84
+ onValueRequest={onValueRequest}
85
+ disabled={disabled}
86
+ />
87
+ ),
88
+ }),
89
+ [copyButtonRef, disabled, onValueRequest, showCopyButton, size, valueToCopy, prefix, postfix],
90
+ );
91
+ }
92
+
93
+ type UseButtonsProps = {
94
+ readonly: boolean;
95
+ showClearButton: boolean;
96
+ showCopyButton: boolean;
97
+ size: 's' | 'm' | 'l';
98
+ onClear(): void;
99
+ inputRef: RefObject<HTMLInputElement>;
100
+ valueToCopy?: string;
101
+ };
102
+
103
+ export function useButtons({
104
+ readonly,
105
+ showClearButton,
106
+ showCopyButton,
107
+ size,
108
+ onClear,
109
+ inputRef,
110
+ valueToCopy = '',
111
+ }: UseButtonsProps) {
112
+ const clearButtonRef = useRef<HTMLButtonElement>(null);
113
+ const copyButtonRef = useRef<HTMLButtonElement>(null);
114
+
115
+ const buttonsRefs: (Element | null)[] = [copyButtonRef.current, clearButtonRef.current];
116
+
117
+ const clearButtonSettings = useClearButton({
118
+ clearButtonRef,
119
+ showClearButton: !readonly && showClearButton,
120
+ size,
121
+ onClear,
122
+ });
123
+ const copyButtonSettings = useCopyButton({
124
+ copyButtonRef,
125
+ showCopyButton: readonly && showCopyButton,
126
+ size,
127
+ valueToCopy,
128
+ });
129
+ const { onInputKeyDown: inputKeyDownNavigationHandler, postfixButtons } = useButtonNavigation({
130
+ inputRef,
131
+ postfixButtons: useMemo(() => [clearButtonSettings, copyButtonSettings], [clearButtonSettings, copyButtonSettings]),
132
+ onButtonKeyDown: undefined,
133
+ readonly,
134
+ submitKeys: ['Enter', 'Space', 'Tab'],
135
+ });
136
+
137
+ return { postfixButtons, inputKeyDownNavigationHandler, buttonsRefs };
138
+ }
139
+
140
+ export function useSearchInput({
141
+ value,
142
+ onChange,
143
+ defaultValue,
144
+ selectedOptionFormatter,
145
+ }: SearchState & { selectedOptionFormatter: SelectedOptionFormatter }) {
146
+ const [inputValue = '', setInputValue] = useValueControl<string>({ value, onChange, defaultValue });
147
+
148
+ const prevInputValue = useRef<string>(inputValue);
149
+
150
+ const updateInputValue = useCallback(
151
+ (selectedItem?: ItemWithId) => {
152
+ const newInputValue = selectedOptionFormatter(selectedItem);
153
+
154
+ if (inputValue !== newInputValue || prevInputValue.current !== newInputValue) {
155
+ setInputValue(newInputValue);
156
+
157
+ prevInputValue.current = newInputValue;
158
+ }
159
+ },
160
+ [inputValue, selectedOptionFormatter, setInputValue],
161
+ );
162
+
163
+ return { inputValue, setInputValue, prevInputValue, onInputValueChange: setInputValue, updateInputValue };
164
+ }
165
+
166
+ export function useHandleDeleteItem(setValue: Handler) {
167
+ return useCallback(
168
+ (item?: ItemWithId) => (e?: MouseEvent<HTMLButtonElement>) => {
169
+ e?.stopPropagation();
170
+
171
+ if (!item) {
172
+ return;
173
+ }
174
+
175
+ if (isAccordionItemProps(item) || isNextListItemProps(item)) {
176
+ const removeIds = extractChildIds({ items: item.items }).concat(item.id ?? '');
177
+
178
+ setValue((value: SelectionSingleValueType[]) => value?.filter(v => !removeIds.includes(v ?? '')));
179
+ return;
180
+ }
181
+
182
+ if (isBaseOptionProps(item)) {
183
+ setValue((value: SelectionSingleValueType[]) =>
184
+ value?.filter(
185
+ v =>
186
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
187
+ // @ts-expect-error
188
+ v !== item.id,
189
+ ),
190
+ );
191
+ }
192
+ },
193
+ [setValue],
194
+ );
195
+ }
@@ -0,0 +1,13 @@
1
+ export { MobileFieldSelect } from './MobileFieldSelect';
2
+
3
+ export type {
4
+ MobileFieldSelectSingleProps,
5
+ MobileFieldSelectMultipleProps,
6
+ MobileFieldSelectProps,
7
+ OptionProps,
8
+ BaseOptionProps,
9
+ AccordionOptionProps,
10
+ NestListOptionProps,
11
+ GroupOptionProps,
12
+ SelectedOptionFormatter,
13
+ } from './types';
@@ -0,0 +1,53 @@
1
+ import { useEffect, useMemo } from 'react';
2
+
3
+ import { ItemProps, useSelectionContext } from '@snack-uikit/list';
4
+
5
+ import { extractAllChildIds, extractChildIds } from '../../utils';
6
+
7
+ type UseGroupItemSelectionProps = {
8
+ items: ItemProps[];
9
+ id?: string | number;
10
+ disabled?: boolean;
11
+ };
12
+
13
+ export function useLegacyGroupItemSelection({ id = '', items, disabled }: UseGroupItemSelectionProps) {
14
+ const { value, setValue, isSelectionMultiple } = useSelectionContext();
15
+ const { childIds, allChildIds } = useMemo(
16
+ () => ({ childIds: extractChildIds({ items }), allChildIds: extractAllChildIds({ items }) }),
17
+ [items],
18
+ );
19
+
20
+ const isIndeterminate = isSelectionMultiple
21
+ ? allChildIds.some(childId => value?.includes(childId))
22
+ : allChildIds.includes(value ?? '');
23
+ const checked = isSelectionMultiple ? allChildIds.every(childId => value?.includes(childId)) : undefined;
24
+
25
+ useEffect(() => {
26
+ if (isSelectionMultiple) {
27
+ if (checked && !value?.includes(id)) {
28
+ setValue?.((value: Array<number | string>) => (value ?? []).concat([id ?? '']));
29
+ }
30
+ if (!checked && value?.includes(id)) {
31
+ setValue?.((value: Array<number | string>) => (value ?? []).filter(itemId => itemId !== id));
32
+ }
33
+ }
34
+ }, [checked, disabled, id, isSelectionMultiple, setValue, value]);
35
+
36
+ const handleOnSelect = () => {
37
+ if (checked) {
38
+ setValue?.((value: Array<string | number>) =>
39
+ (value ?? []).filter(itemId => itemId !== id && !childIds.includes(itemId)),
40
+ );
41
+ return;
42
+ }
43
+
44
+ if (isIndeterminate) {
45
+ setValue?.((value: Array<string | number>) => Array.from(new Set([...(value ?? []), ...childIds, id])));
46
+ return;
47
+ }
48
+
49
+ setValue?.((value: Array<string | number>) => (value ?? []).concat([...childIds, id ?? '']));
50
+ };
51
+
52
+ return { checked, isIndeterminate, handleOnSelect };
53
+ }
@@ -0,0 +1 @@
1
+ export { useLegacyGroupItemSelection } from './Items/hooks';
@@ -0,0 +1,38 @@
1
+ import FuzzySearch from 'fuzzy-search';
2
+ import get from 'lodash/get';
3
+ import { useCallback, useMemo } from 'react';
4
+
5
+ import { ItemProps, kindFlattenItems } from '@snack-uikit/list';
6
+
7
+ const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 1;
8
+
9
+ const COMMON_FIELDS_TO_SEARCH = ['content.option', 'content.caption', 'content.description'];
10
+
11
+ /**
12
+ * Поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
13
+ */
14
+ export function useSearch(items: ItemProps[], enableFuzzySearch: boolean): (value: string) => ItemProps[] {
15
+ const flattenItems = useMemo(() => {
16
+ const { flattenItems } = kindFlattenItems({ items });
17
+
18
+ return Object.values(flattenItems);
19
+ }, [items]);
20
+
21
+ return useCallback(
22
+ (search: string) => {
23
+ if (!enableFuzzySearch) {
24
+ return flattenItems.filter(item =>
25
+ COMMON_FIELDS_TO_SEARCH.some(key => {
26
+ const value: string | undefined = get(item, key);
27
+ return value?.toLowerCase().includes(search.toLowerCase());
28
+ }),
29
+ );
30
+ }
31
+
32
+ const searcher = new FuzzySearch(flattenItems, COMMON_FIELDS_TO_SEARCH, {});
33
+
34
+ return search.length >= DEFAULT_MIN_SEARCH_INPUT_LENGTH ? searcher.search(search) : items;
35
+ },
36
+ [enableFuzzySearch, flattenItems, items],
37
+ );
38
+ }
@@ -0,0 +1,3 @@
1
+ export * from './components';
2
+ export { useSearch } from './hooks';
3
+ export { extractChildIds, flattenItems } from './utils';
@@ -0,0 +1,176 @@
1
+ import { RefObject } from 'react';
2
+
3
+ import {
4
+ AccordionItemProps,
5
+ BaseItemProps,
6
+ isAccordionItemProps,
7
+ isBaseItemProps,
8
+ isGroupItemProps,
9
+ isNextListItemProps,
10
+ ItemProps,
11
+ NextListItemProps,
12
+ } from '@snack-uikit/list';
13
+
14
+ type WithCollapsedItemsProps = {
15
+ items: ItemProps[];
16
+ openCollapsedItems: Array<number | string>;
17
+ };
18
+
19
+ type WithCollapsedItemsReturnType = {
20
+ items: ItemProps[];
21
+ ids: Array<string | number>;
22
+ expandedIds: Array<string | number>;
23
+ itemRefs: RefObject<HTMLElement>[];
24
+ };
25
+
26
+ export function withCollapsedItems({
27
+ items,
28
+ openCollapsedItems,
29
+ }: WithCollapsedItemsProps): WithCollapsedItemsReturnType {
30
+ let itemRefs: WithCollapsedItemsReturnType['itemRefs'] = [];
31
+ let newItems: WithCollapsedItemsReturnType['items'] = [];
32
+ let ids: WithCollapsedItemsReturnType['ids'] = [];
33
+ let expandedIds: WithCollapsedItemsReturnType['expandedIds'] = [];
34
+
35
+ items.forEach(item => {
36
+ if (
37
+ ((isBaseItemProps(item) && !item.inactive) || isNextListItemProps(item) || isAccordionItemProps(item)) &&
38
+ !item.disabled
39
+ ) {
40
+ newItems = newItems.concat([item]);
41
+ ids = ids.concat([item.id ?? '']);
42
+
43
+ if (item.itemRef) {
44
+ itemRefs = itemRefs.concat([item.itemRef]);
45
+ }
46
+ }
47
+
48
+ if (isNextListItemProps(item) && item.id && !item.disabled) {
49
+ expandedIds = expandedIds.concat(item.id);
50
+ }
51
+
52
+ if (isGroupItemProps(item)) {
53
+ const { itemRefs: nestedItemsRefs, ids: nestedIds } = withCollapsedItems({
54
+ items: item.items,
55
+ openCollapsedItems,
56
+ });
57
+
58
+ ids = ids.concat(nestedIds);
59
+
60
+ itemRefs = itemRefs.concat(nestedItemsRefs);
61
+ }
62
+
63
+ if (isAccordionItemProps(item) && item.id && openCollapsedItems.includes(item.id)) {
64
+ const {
65
+ itemRefs: nestedItemsRefs,
66
+ ids: nestedIds,
67
+ items: nestedItems,
68
+ expandedIds: nestedExpandedIds,
69
+ } = withCollapsedItems({
70
+ items: item.items,
71
+ openCollapsedItems,
72
+ });
73
+
74
+ ids = ids.concat(nestedIds);
75
+ newItems = newItems.concat(nestedItems);
76
+ itemRefs = itemRefs.concat(nestedItemsRefs);
77
+ expandedIds = expandedIds.concat(nestedExpandedIds);
78
+ }
79
+ });
80
+
81
+ return { items, itemRefs, ids, expandedIds };
82
+ }
83
+
84
+ /**
85
+ * Функция возвращает массив id дочерних items
86
+ * @function extractItemIds
87
+ */
88
+
89
+ export function extractItemIds(items: ItemProps[]): Array<string | number> {
90
+ return items.reduce(
91
+ (prev: Array<string | number>, item: ItemProps) => {
92
+ if (isGroupItemProps(item)) {
93
+ return prev.concat(extractItemIds(item.items));
94
+ }
95
+ return item.id ? prev.concat([item.id]) : prev;
96
+ },
97
+ [] as Array<string | number>,
98
+ );
99
+ }
100
+
101
+ export function extractChildIds({ items }: { items: ItemProps[] }): Array<string | number> {
102
+ return items
103
+ .filter(
104
+ item =>
105
+ isAccordionItemProps(item) ||
106
+ isNextListItemProps(item) ||
107
+ isGroupItemProps(item) ||
108
+ (isBaseItemProps(item) && !item.disabled && !item.inactive),
109
+ )
110
+ .reduce(
111
+ (prev: Array<string | number>, item: ItemProps) => {
112
+ if (isAccordionItemProps(item) || isNextListItemProps(item)) {
113
+ return prev.concat([item.id ?? '']).concat(extractChildIds({ items: item.items }));
114
+ }
115
+
116
+ if (isGroupItemProps(item)) {
117
+ return prev.concat(extractChildIds({ items: item.items }));
118
+ }
119
+
120
+ return item.id && !isGroupItemProps(item) ? prev.concat([item.id]) : prev;
121
+ },
122
+ [] as Array<string | number>,
123
+ );
124
+ }
125
+
126
+ export function extractAllChildIds({ items }: { items: ItemProps[] }): Array<string | number> {
127
+ return items
128
+ .filter(
129
+ item =>
130
+ isAccordionItemProps(item) ||
131
+ isNextListItemProps(item) ||
132
+ isGroupItemProps(item) ||
133
+ (isBaseItemProps(item) && !item.inactive),
134
+ )
135
+ .reduce(
136
+ (prev: Array<string | number>, item: ItemProps) => {
137
+ if (isAccordionItemProps(item) || isNextListItemProps(item)) {
138
+ return prev.concat([item.id ?? '']).concat(extractAllChildIds({ items: item.items }));
139
+ }
140
+
141
+ if (isGroupItemProps(item)) {
142
+ return prev.concat(extractAllChildIds({ items: item.items }));
143
+ }
144
+
145
+ return item.id && !isGroupItemProps(item) ? prev.concat([item.id]) : prev;
146
+ },
147
+ [] as Array<string | number>,
148
+ );
149
+ }
150
+
151
+ /**
152
+ * Функция разворачивает массив айтемов в плоский список
153
+ * @function flattenItems
154
+ */
155
+
156
+ export function flattenItems(items: ItemProps[]): (BaseItemProps | AccordionItemProps | NextListItemProps)[] {
157
+ const flattenItems: (BaseItemProps | AccordionItemProps | NextListItemProps)[] = [];
158
+
159
+ function flatten(item: ItemProps) {
160
+ if (!isGroupItemProps(item)) {
161
+ flattenItems.push(item);
162
+ }
163
+
164
+ if ('items' in item) {
165
+ for (const nestedItem of item.items) {
166
+ flatten(nestedItem);
167
+ }
168
+ }
169
+ }
170
+
171
+ for (const item of items) {
172
+ flatten(item);
173
+ }
174
+
175
+ return flattenItems;
176
+ }
@@ -0,0 +1,176 @@
1
+ @use '@sbercloud/figma-tokens-cloud-platform/build/scss/components/styles-tokens-element';
2
+ @use '@sbercloud/figma-tokens-cloud-platform/build/scss/components/styles-tokens-fields';
3
+
4
+ $sizes: 's', 'm', 'l';
5
+ $containerVariant: 'single-line-container';
6
+ $icons-sizes: (
7
+ 's': styles-tokens-element.$icon-xs,
8
+ 'm': styles-tokens-element.$icon-s,
9
+ 'l': styles-tokens-element.$icon-s,
10
+ );
11
+
12
+ $base-min-width: 4px;
13
+
14
+ .triggerClassName {
15
+ --offset: #{styles-tokens-fields.$space-drop-list-drop-offset};
16
+
17
+ width: 100%;
18
+ }
19
+
20
+ .contentWrapper {
21
+ position: relative;
22
+
23
+ overflow: hidden;
24
+ display: flex;
25
+ flex-wrap: wrap;
26
+
27
+ width: 100%;
28
+ }
29
+
30
+ .tagContainer {
31
+ /* stylelint-disable-next-line declaration-no-important */
32
+ height: auto !important;
33
+
34
+ @each $size in $sizes {
35
+ &[data-size='#{$size}'] {
36
+ @include styles-tokens-fields.composite-var(styles-tokens-fields.$fields, 'select-multiple', $size);
37
+
38
+ .contentWrapper {
39
+ gap: styles-tokens-fields.simple-var(styles-tokens-fields.$fields, 'select-multiple', $size, 'gap');
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ .container {
46
+ position: relative;
47
+
48
+ @each $size in $sizes {
49
+ &[data-size='#{$size}'] {
50
+ .inputPlug {
51
+ @include styles-tokens-fields.composite-var(styles-tokens-fields.$theme-variables, 'sans', 'body', $size);
52
+ }
53
+
54
+ .arrowIcon {
55
+ width: styles-tokens-fields.simple-var($icons-sizes, $size) !important; /* stylelint-disable-line declaration-no-important */
56
+ height: styles-tokens-fields.simple-var($icons-sizes, $size) !important; /* stylelint-disable-line declaration-no-important */
57
+ color: styles-tokens-fields.$sys-neutral-text-light;
58
+ }
59
+
60
+ &[data-variant='#{$containerVariant}'] {
61
+ .displayValue {
62
+ $button-width: styles-tokens-fields.simple-var($icons-sizes, $size);
63
+ $postfix-width: calc(var(#{styles-tokens-fields.$space-fields-postfix-gap}) + $button-width * 2);
64
+ $margin-right: calc(
65
+ #{styles-tokens-fields.simple-var(styles-tokens-fields.$fields, $containerVariant, $size, 'padding-right')} + #{styles-tokens-fields.simple-var(styles-tokens-fields.$fields, $containerVariant, $size, 'gap')} + #{$postfix-width}
66
+ );
67
+
68
+ width: calc(100% - $margin-right);
69
+ margin-right: $margin-right;
70
+ padding-left: styles-tokens-fields.simple-var(styles-tokens-fields.$fields, $containerVariant, $size, 'padding-left');
71
+ border-radius: styles-tokens-fields.simple-var(styles-tokens-fields.$fields, $containerVariant, $size, 'border-radius');
72
+ }
73
+ }
74
+ }
75
+ }
76
+
77
+ &:hover,
78
+ &:focus-within,
79
+ &[data-focused] {
80
+ .arrowIcon {
81
+ color: styles-tokens-fields.$sys-neutral-text-support;
82
+ }
83
+ }
84
+
85
+ &[data-disabled],
86
+ &[data-readonly] {
87
+ .arrowIcon {
88
+ color: styles-tokens-fields.$sys-neutral-text-disabled;
89
+ }
90
+ }
91
+ }
92
+
93
+ .inputPlug {
94
+ content: '';
95
+
96
+ position: absolute;
97
+ top: 0;
98
+ left: 0;
99
+
100
+ overflow: hidden;
101
+
102
+ width: fit-content;
103
+ max-width: 100%;
104
+ height: 0;
105
+ }
106
+
107
+ .inputWrapper {
108
+ position: relative;
109
+
110
+ display: inline-flex;
111
+ flex: 1;
112
+
113
+ color: transparent;
114
+
115
+ &[data-searchable='false'] {
116
+ width: 0;
117
+ min-width: 0;
118
+ max-width: 0;
119
+ }
120
+ }
121
+
122
+ .postfix {
123
+ display: inline-flex;
124
+ flex-shrink: 0;
125
+ gap: styles-tokens-fields.$space-fields-postfix-gap;
126
+ }
127
+
128
+ input.readonlyCursor {
129
+ cursor: pointer;
130
+ caret-color: transparent;
131
+ }
132
+
133
+ .searchDivider {
134
+ margin-bottom: 4px;
135
+ }
136
+
137
+ .footer {
138
+ width: 100%;
139
+ }
140
+
141
+ .footerTopLine {
142
+ display: flex;
143
+ align-items: center;
144
+ justify-content: space-between;
145
+ gap: 4px;
146
+ }
147
+
148
+ .counter {
149
+ @include styles-tokens-fields.composite-var(styles-tokens-fields.$sans-body-m);
150
+
151
+ color: styles-tokens-fields.$sys-neutral-text-light;
152
+ }
153
+
154
+ .listWrapper {
155
+ @include styles-tokens-fields.composite-var(styles-tokens-fields.$sans-body-m);
156
+
157
+ flex: 1 1 auto;
158
+ box-sizing: border-box;
159
+ min-height: styles-tokens-fields.$dimension-2m;
160
+ color: styles-tokens-fields.$sys-neutral-text-main;
161
+ padding: 16px 0;
162
+ }
163
+
164
+ .body {
165
+ @include styles-tokens-fields.composite-var(styles-tokens-fields.$sans-body-m);
166
+
167
+ flex: 1 1 auto;
168
+ box-sizing: border-box;
169
+ min-height: styles-tokens-fields.$dimension-2m;
170
+ color: styles-tokens-fields.$sys-neutral-text-main;
171
+ }
172
+
173
+ .bodyNoPadding {
174
+ /* stylelint-disable-next-line declaration-no-important */
175
+ padding: 0 !important;
176
+ }