@rescui/select 0.15.0 → 0.15.1-RUI-280-Update-select-component-e516591ed.54
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/lib/_virtual/index.css.js +12 -12
- package/lib/common-prop-types.d.ts +9 -14
- package/lib/common-prop-types.js +4 -3
- package/lib/constants.d.ts +7 -0
- package/lib/constants.js +8 -0
- package/lib/hooks/use-css-context-transfer.d.ts +14 -0
- package/lib/hooks/use-css-context-transfer.js +40 -0
- package/lib/hooks/use-label-focus.d.ts +11 -0
- package/lib/hooks/use-label-focus.js +28 -0
- package/lib/hooks/use-multi-option-serialization.d.ts +10 -0
- package/lib/hooks/use-multi-option-serialization.js +82 -0
- package/lib/hooks/use-option-serialization.d.ts +10 -0
- package/lib/hooks/use-option-serialization.js +59 -0
- package/lib/index.css +2004 -837
- package/lib/index.d.ts +4 -6
- package/lib/index.js +3 -3
- package/lib/multiselect.d.ts +29 -0
- package/lib/multiselect.js +239 -0
- package/lib/native-select.d.ts +4 -0
- package/lib/native-select.js +182 -0
- package/lib/parts/foldable.js +5 -7
- package/lib/parts/form-trigger-wrapper.d.ts +7 -7
- package/lib/parts/form-trigger-wrapper.js +16 -34
- package/lib/parts/icons.d.ts +17 -0
- package/lib/parts/icons.js +75 -0
- package/lib/parts/list-box.d.ts +19 -0
- package/lib/parts/list-box.js +146 -0
- package/lib/parts/multi-trigger.d.ts +11 -0
- package/lib/parts/multi-trigger.js +62 -0
- package/lib/parts/native-select-options-with-groups.d.ts +8 -0
- package/lib/parts/native-select-options-with-groups.js +76 -0
- package/lib/parts/native-select-trigger.d.ts +18 -0
- package/lib/parts/native-select-trigger.js +54 -0
- package/lib/parts/popover.d.ts +12 -0
- package/lib/parts/popover.js +62 -0
- package/lib/parts/popup-content.d.ts +19 -0
- package/lib/parts/popup-content.js +76 -0
- package/lib/public-api.p.css +486 -444
- package/lib/public-api.pcss +486 -444
- package/lib/select-basic.d.ts +3 -0
- package/lib/select-basic.js +143 -0
- package/lib/select-searchable.d.ts +3 -0
- package/lib/select-searchable.js +168 -0
- package/lib/select.d.ts +27 -91
- package/lib/select.js +53 -360
- package/lib/styles/common.p.module.css.js +27 -0
- package/lib/styles/form-trigger.p.module.css.js +15 -0
- package/lib/styles/list-box.p.module.css.js +16 -0
- package/lib/styles/native-select-trigger.p.module.css.js +17 -0
- package/lib/styles/native-select.p.module.css.js +9 -0
- package/lib/styles/popover.p.module.css.js +10 -0
- package/lib/types.d.ts +167 -4
- package/lib/utils/calculate-max-height-by-items.d.ts +13 -0
- package/lib/utils/calculate-max-height-by-items.js +22 -0
- package/lib/utils/convert-options.d.ts +3 -0
- package/lib/utils/convert-options.js +52 -0
- package/lib/utils/convert-placement.d.ts +3 -0
- package/lib/utils/convert-placement.js +22 -0
- package/lib/utils/css-vars-utils.d.ts +3 -0
- package/lib/utils/css-vars-utils.js +20 -0
- package/lib/utils/get-empty-message.d.ts +6 -0
- package/lib/utils/get-empty-message.js +32 -0
- package/lib/utils/get-option-value.d.ts +2 -0
- package/lib/utils/get-option-value.js +11 -0
- package/lib/utils/get-real-items-cnt.d.ts +2 -0
- package/lib/utils/get-real-items-cnt.js +21 -0
- package/lib/utils/get-text-from-nodes.d.ts +2 -0
- package/lib/utils/get-text-from-nodes.js +28 -0
- package/lib/utils/is-option-a-group.d.ts +2 -0
- package/lib/utils/is-option-a-group.js +5 -0
- package/lib/utils/throttle.d.ts +1 -0
- package/package.json +11 -12
- package/lib/key-codes.d.ts +0 -7
- package/lib/key-codes.js +0 -8
- package/lib/parts/common-select.p.module.css.js +0 -15
- package/lib/parts/form-trigger.p.module.css.js +0 -15
- package/lib/parts/multiselect.d.ts +0 -86
- package/lib/parts/multiselect.js +0 -455
- package/lib/parts/native-select.d.ts +0 -36
- package/lib/parts/native-select.js +0 -257
- package/lib/parts/native-select.p.module.css.js +0 -9
- package/lib/parts/throttle.d.ts +0 -1
- package/lib/parts/trigger.d.ts +0 -37
- package/lib/parts/trigger.js +0 -255
- package/lib/parts/trigger.p.module.css.js +0 -31
- package/lib/parts/use-backward-compatible-id.d.ts +0 -4
- package/lib/parts/use-backward-compatible-id.js +0 -14
- package/lib/utils.d.ts +0 -22
- package/lib/utils.js +0 -201
- /package/lib/{parts → hooks}/use-observable-force-rerender.d.ts +0 -0
- /package/lib/{parts → hooks}/use-observable-force-rerender.js +0 -0
- /package/lib/{parts → utils}/throttle.js +0 -0
package/lib/types.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { Theme } from '@rescui/ui-contexts';
|
|
3
|
+
import type { AriaComboBoxProps } from '@react-aria/combobox';
|
|
4
|
+
import type { AriaSelectProps } from '@react-aria/select';
|
|
5
|
+
import type { AriaPositionProps, AriaFieldProps } from 'react-aria';
|
|
6
|
+
import type { SelectState } from '@react-stately/select';
|
|
7
|
+
import type { ComboBoxState } from '@react-stately/combobox';
|
|
8
|
+
import type { Key } from 'react-stately';
|
|
9
|
+
export type { Key } from 'react-stately';
|
|
10
|
+
export declare type Placement = 'auto-start' | 'auto' | 'auto-end' | 'top-start' | 'top' | 'top-end' | 'right-start' | 'right' | 'right-end' | 'bottom-end' | 'bottom' | 'bottom-start' | 'left-end' | 'left' | 'left-start';
|
|
11
|
+
export declare type AriaPlacement = AriaPositionProps['placement'];
|
|
2
12
|
export declare type SelectSize = 'l' | 'm' | 's';
|
|
3
13
|
export declare type SelectMode = 'classic' | 'rock';
|
|
4
14
|
export declare type SelectOption = {
|
|
5
15
|
label: React.ReactNode;
|
|
6
|
-
value?:
|
|
16
|
+
value?: Key;
|
|
7
17
|
};
|
|
8
18
|
export declare type SelectOptionsGroup = {
|
|
9
19
|
label?: React.ReactNode;
|
|
@@ -13,7 +23,7 @@ export declare type SelectOptionOrGroup = SelectOption | SelectOptionsGroup;
|
|
|
13
23
|
export declare type SelectOptions = SelectOptionOrGroup[];
|
|
14
24
|
export declare type NativeSelectOption = {
|
|
15
25
|
label: string;
|
|
16
|
-
value?:
|
|
26
|
+
value?: Key;
|
|
17
27
|
disabled?: boolean;
|
|
18
28
|
};
|
|
19
29
|
export declare type NativeSelectOptionsGroup = {
|
|
@@ -24,11 +34,164 @@ export declare type NativeSelectOptionsGroup = {
|
|
|
24
34
|
export declare type NativeSelectOptionOrGroup = NativeSelectOption | NativeSelectOptionsGroup;
|
|
25
35
|
export declare type NativeSelectOptions = NativeSelectOptionOrGroup[];
|
|
26
36
|
export declare type Groups = SelectOptionsGroup[];
|
|
27
|
-
export declare type Index = [number, number];
|
|
28
|
-
export declare type FilterFn = (option: SelectOption) => boolean;
|
|
29
37
|
export declare type NoOptionsMessageConfig = {
|
|
30
38
|
noOptions: string;
|
|
31
39
|
nothingFound?: string;
|
|
32
40
|
loading?: string;
|
|
33
41
|
};
|
|
34
42
|
export declare type NoOptionsMessage = string | NoOptionsMessageConfig;
|
|
43
|
+
export declare type SelectProps = {
|
|
44
|
+
/**
|
|
45
|
+
* Value of the select
|
|
46
|
+
*/
|
|
47
|
+
value?: SelectOption | null;
|
|
48
|
+
/**
|
|
49
|
+
* Change value callback. `value => ...`. Pass `null` on clear.
|
|
50
|
+
*/
|
|
51
|
+
onChange?: (newValue: SelectOption | null) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Additional class name
|
|
54
|
+
*/
|
|
55
|
+
className?: string;
|
|
56
|
+
style?: React.CSSProperties;
|
|
57
|
+
id?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Array of options or option groups
|
|
60
|
+
*/
|
|
61
|
+
options?: (SelectOption | SelectOptionsGroup)[] | null;
|
|
62
|
+
/**
|
|
63
|
+
* Is select supports clearing the value
|
|
64
|
+
*/
|
|
65
|
+
isClearable?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Is select supports inplace filtering
|
|
68
|
+
*/
|
|
69
|
+
isSearchable?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Is the component has been disabled
|
|
72
|
+
*/
|
|
73
|
+
isDisabled?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Is loader displayed inside the trigger part
|
|
76
|
+
*/
|
|
77
|
+
isLoading?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* A hint to the user of what can be entered in the control
|
|
80
|
+
*/
|
|
81
|
+
placeholder?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Size
|
|
84
|
+
*/
|
|
85
|
+
size?: SelectSize;
|
|
86
|
+
/**
|
|
87
|
+
* Appearance mode
|
|
88
|
+
*/
|
|
89
|
+
mode?: SelectMode;
|
|
90
|
+
/**
|
|
91
|
+
* Appearance theme
|
|
92
|
+
*/
|
|
93
|
+
theme?: Theme;
|
|
94
|
+
/**
|
|
95
|
+
* Error state flag or `React.ReactNode` (use with forms)
|
|
96
|
+
*/
|
|
97
|
+
error?: boolean | React.ReactNode;
|
|
98
|
+
/**
|
|
99
|
+
* If `true`, there will be reserved a space for a 1-line error message. Subsequent lines will be placed below normally.
|
|
100
|
+
* If `false`, there will be no reservation.
|
|
101
|
+
*/
|
|
102
|
+
reserveErrorLine?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Label element (use with forms)
|
|
105
|
+
*/
|
|
106
|
+
label?: React.ReactNode;
|
|
107
|
+
/**
|
|
108
|
+
* If `true`, label will be bold
|
|
109
|
+
*/
|
|
110
|
+
boldLabel?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Placement of dropdown element
|
|
113
|
+
*/
|
|
114
|
+
placement?: Placement;
|
|
115
|
+
/**
|
|
116
|
+
* Note element at the bottom (use with forms)
|
|
117
|
+
*/
|
|
118
|
+
note?: React.ReactNode;
|
|
119
|
+
/**
|
|
120
|
+
* Text to display when there are no options
|
|
121
|
+
*/
|
|
122
|
+
noOptionsMessage?: NoOptionsMessage;
|
|
123
|
+
/**
|
|
124
|
+
* Input name attribute
|
|
125
|
+
*/
|
|
126
|
+
name?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Maximum number of fully visible items in the dropdown list.
|
|
129
|
+
* For large lists, `n + 0.5` items will be visible at a time.
|
|
130
|
+
* If the maximum number of items in a list is exactly `n + 1`, all
|
|
131
|
+
* items will be shown instead (to avoid creating a scroll for half an item only).
|
|
132
|
+
*/
|
|
133
|
+
maxVisibleItems?: number;
|
|
134
|
+
};
|
|
135
|
+
export declare type MultiselectProps = {
|
|
136
|
+
/**
|
|
137
|
+
* Value of the multiselect (array of selected options)
|
|
138
|
+
*/
|
|
139
|
+
value?: SelectOption[] | null;
|
|
140
|
+
/**
|
|
141
|
+
* Change value callback. `value => ...`. Pass `[]` on clear.
|
|
142
|
+
*/
|
|
143
|
+
onChange?: (newValue: SelectOption[]) => void;
|
|
144
|
+
/**
|
|
145
|
+
* Display tags in single line with "+N" counter
|
|
146
|
+
*/
|
|
147
|
+
isSingleLine?: boolean;
|
|
148
|
+
} & Omit<SelectProps, 'value' | 'onChange' | 'isSearchable'>;
|
|
149
|
+
export declare type TriggerFuncProps = {
|
|
150
|
+
selectedLabel?: string;
|
|
151
|
+
selectedValue?: Key;
|
|
152
|
+
placeholder?: string;
|
|
153
|
+
hovered: boolean;
|
|
154
|
+
focused: boolean;
|
|
155
|
+
};
|
|
156
|
+
export declare type NativeSelectProps = {
|
|
157
|
+
options?: (NativeSelectOption | NativeSelectOptionsGroup)[];
|
|
158
|
+
size?: SelectSize;
|
|
159
|
+
theme?: Theme;
|
|
160
|
+
className?: string;
|
|
161
|
+
id?: string;
|
|
162
|
+
style?: React.CSSProperties;
|
|
163
|
+
value?: NativeSelectOption | null;
|
|
164
|
+
onChange?: (newValue: NativeSelectOption | null) => void;
|
|
165
|
+
placeholder?: string;
|
|
166
|
+
isLoading?: boolean;
|
|
167
|
+
isDisabled?: boolean;
|
|
168
|
+
trigger?: (props: TriggerFuncProps) => React.ReactNode;
|
|
169
|
+
label?: React.ReactNode;
|
|
170
|
+
note?: React.ReactNode;
|
|
171
|
+
error?: boolean | React.ReactNode;
|
|
172
|
+
/**
|
|
173
|
+
* If `true`, there will be reserved a space for a 1-line error message. Subsequent lines will be placed below normally.
|
|
174
|
+
* If `false`, there will be no reservation.
|
|
175
|
+
*/
|
|
176
|
+
reserveErrorLine?: boolean;
|
|
177
|
+
noOptionsMessage?: NoOptionsMessage;
|
|
178
|
+
name?: string;
|
|
179
|
+
boldLabel?: boolean;
|
|
180
|
+
} & Omit<AriaFieldProps, 'isInvalid' | 'errorMessage' | 'description' | 'id' | 'label' | 'labelElementType' | 'validate' | 'validationBehavior' | 'validationState'>;
|
|
181
|
+
export declare type InnerSingleComponentProps<T extends object> = {
|
|
182
|
+
size?: SelectSize;
|
|
183
|
+
mode?: SelectMode;
|
|
184
|
+
theme?: Theme;
|
|
185
|
+
style?: React.CSSProperties;
|
|
186
|
+
className?: string;
|
|
187
|
+
isClearable?: boolean;
|
|
188
|
+
isLoading?: boolean;
|
|
189
|
+
errorMessage?: React.ReactNode;
|
|
190
|
+
placement?: AriaPlacement;
|
|
191
|
+
boldLabel?: boolean;
|
|
192
|
+
reserveErrorLine?: boolean;
|
|
193
|
+
placeholder?: string;
|
|
194
|
+
noOptionsMessage?: NoOptionsMessage;
|
|
195
|
+
maxVisibleItems?: number;
|
|
196
|
+
} & Omit<AriaSelectProps<T, 'single'> | AriaComboBoxProps<T, 'single'>, 'errorMessage' | 'validate'>;
|
|
197
|
+
export declare type CommonState<T extends object> = SelectState<T, 'single'> | SelectState<T, 'multiple'> | ComboBoxState<T>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate the max height of the list based on items count and allowedMaxVisibleItems.
|
|
3
|
+
* Instead of simply adding 0.5 to the allowedMaxVisibleItems, we process
|
|
4
|
+
* `itemsCount == allowedMaxVisibleItems + 1` differently.
|
|
5
|
+
*
|
|
6
|
+
* For allowedMaxVisibleItems={5}:
|
|
7
|
+
* - If items itemsCount <= 5: restrain by 5.5 items (to avoid scrollbar due to layout shifts)
|
|
8
|
+
* - If items itemsCount = 6: restrain by all 6.1 items (6 + 0.1 for group separators)
|
|
9
|
+
* - If items itemsCount > 6: restrain by 5.5 items
|
|
10
|
+
*
|
|
11
|
+
* Formula: max(5.5, min(itemsCount + 0.1, 6.1) - min(max(0, itemsCount - 6), 0.6))
|
|
12
|
+
*/
|
|
13
|
+
export declare const calculateMaxHeightByItems: (itemsCount: number, allowedMaxVisibleItems: number) => number;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculate the max height of the list based on items count and allowedMaxVisibleItems.
|
|
3
|
+
* Instead of simply adding 0.5 to the allowedMaxVisibleItems, we process
|
|
4
|
+
* `itemsCount == allowedMaxVisibleItems + 1` differently.
|
|
5
|
+
*
|
|
6
|
+
* For allowedMaxVisibleItems={5}:
|
|
7
|
+
* - If items itemsCount <= 5: restrain by 5.5 items (to avoid scrollbar due to layout shifts)
|
|
8
|
+
* - If items itemsCount = 6: restrain by all 6.1 items (6 + 0.1 for group separators)
|
|
9
|
+
* - If items itemsCount > 6: restrain by 5.5 items
|
|
10
|
+
*
|
|
11
|
+
* Formula: max(5.5, min(itemsCount + 0.1, 6.1) - min(max(0, itemsCount - 6), 0.6))
|
|
12
|
+
*/
|
|
13
|
+
const calculateMaxHeightByItems = (itemsCount, allowedMaxVisibleItems) => {
|
|
14
|
+
const allowedFloor = Math.floor(allowedMaxVisibleItems);
|
|
15
|
+
const groupSeparatorsDelta = 0.1;
|
|
16
|
+
const partiallyVisiblePart = 0.5;
|
|
17
|
+
const upperLimit = Math.min(itemsCount + groupSeparatorsDelta, allowedFloor + 1 + groupSeparatorsDelta);
|
|
18
|
+
const delta = Math.min(Math.max(0, itemsCount - (allowedFloor + 1)), partiallyVisiblePart + groupSeparatorsDelta);
|
|
19
|
+
return Math.max(allowedFloor + partiallyVisiblePart, upperLimit - delta);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { calculateMaxHeightByItems };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Section, Item } from 'react-stately';
|
|
3
|
+
import { getOptionValue } from './get-option-value.js';
|
|
4
|
+
import { getTextFromNodes } from './get-text-from-nodes.js';
|
|
5
|
+
import { isOptionAGroup } from './is-option-a-group.js';
|
|
6
|
+
import { VIRTUAL_ITEMS_SECTION_KEY } from '../constants.js';
|
|
7
|
+
|
|
8
|
+
const convertOptions = (options, virtualOptions) => [...options.map((item, index) => {
|
|
9
|
+
// Check if it's a group
|
|
10
|
+
if (isOptionAGroup(item)) {
|
|
11
|
+
const group = item;
|
|
12
|
+
|
|
13
|
+
if (!group.options || group.options.length === 0) {
|
|
14
|
+
return null;
|
|
15
|
+
} // Render as Section (with or without label)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
const groupLabelText = group.label ? getTextFromNodes(group.label) : ''; // Use a special prefix that's unlikely to collide with user values
|
|
19
|
+
|
|
20
|
+
const sectionKey = `\0__rs_section_${index}_${groupLabelText}`;
|
|
21
|
+
return /*#__PURE__*/React.createElement(Section, {
|
|
22
|
+
key: sectionKey,
|
|
23
|
+
title: group.label,
|
|
24
|
+
"aria-label": groupLabelText || undefined
|
|
25
|
+
}, group.options.map(option => {
|
|
26
|
+
const key = getOptionValue(option);
|
|
27
|
+
return /*#__PURE__*/React.createElement(Item, {
|
|
28
|
+
key: key,
|
|
29
|
+
textValue: getTextFromNodes(option.label)
|
|
30
|
+
}, option.label);
|
|
31
|
+
}));
|
|
32
|
+
} // It's a single option
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
const option = item;
|
|
36
|
+
const key = getOptionValue(option);
|
|
37
|
+
return /*#__PURE__*/React.createElement(Item, {
|
|
38
|
+
key: key,
|
|
39
|
+
textValue: getTextFromNodes(option.label)
|
|
40
|
+
}, option.label);
|
|
41
|
+
}), virtualOptions.length > 0 && /*#__PURE__*/React.createElement(Section, {
|
|
42
|
+
key: VIRTUAL_ITEMS_SECTION_KEY,
|
|
43
|
+
title: ''
|
|
44
|
+
}, virtualOptions.map(option => {
|
|
45
|
+
const key = getOptionValue(option);
|
|
46
|
+
return /*#__PURE__*/React.createElement(Item, {
|
|
47
|
+
key: key,
|
|
48
|
+
textValue: getTextFromNodes(option.label)
|
|
49
|
+
}, option.label);
|
|
50
|
+
}))].filter(Boolean);
|
|
51
|
+
|
|
52
|
+
export { convertOptions };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const convertPlacement = outsidePlacement => {
|
|
2
|
+
const placementMap = {
|
|
3
|
+
top: 'top',
|
|
4
|
+
'top-start': 'top start',
|
|
5
|
+
'top-end': 'top end',
|
|
6
|
+
bottom: 'bottom',
|
|
7
|
+
'bottom-start': 'bottom start',
|
|
8
|
+
'bottom-end': 'bottom end',
|
|
9
|
+
left: 'left',
|
|
10
|
+
'left-start': 'left top',
|
|
11
|
+
'left-end': 'left bottom',
|
|
12
|
+
right: 'right',
|
|
13
|
+
'right-start': 'right top',
|
|
14
|
+
'right-end': 'right bottom',
|
|
15
|
+
auto: null,
|
|
16
|
+
'auto-start': 'start',
|
|
17
|
+
'auto-end': 'end'
|
|
18
|
+
};
|
|
19
|
+
return placementMap[outsidePlacement] || 'bottom';
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { convertPlacement };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const PRIMARY_COLORS = ['--rs-color-primary-light-theme', '--rs-color-primary-dim-light-theme', '--rs-color-primary-fog-light-theme', '--rs-color-primary-t-dim-light-theme', '--rs-color-primary-t-fog-light-theme', '--rs-color-primary-dark-theme', '--rs-color-primary-dim-dark-theme', '--rs-color-primary-fog-dark-theme', '--rs-color-primary-t-dim-dark-theme', '--rs-color-primary-t-fog-dark-theme'];
|
|
2
|
+
|
|
3
|
+
const extractPrimaryColors = styles => {
|
|
4
|
+
const colors = {};
|
|
5
|
+
PRIMARY_COLORS.forEach(varName => {
|
|
6
|
+
colors[varName] = styles.getPropertyValue(varName) || 'initial';
|
|
7
|
+
});
|
|
8
|
+
return colors;
|
|
9
|
+
};
|
|
10
|
+
/** Check out `@rescui/colors/src/public-api.p.css` file */
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const extractThemeFromCss = styles => {
|
|
14
|
+
const themeDark = parseInt(styles.getPropertyValue('--rs-theme-dark'), 10) || 0;
|
|
15
|
+
const themeFlip = parseInt(styles.getPropertyValue('--rs-theme-flip'), 10) || 0;
|
|
16
|
+
const themeDarkCoefficient = themeDark * (1 - themeFlip) + themeFlip * (1 - themeDark);
|
|
17
|
+
return themeDarkCoefficient === 1 ? 'dark' : 'light';
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { extractPrimaryColors, extractThemeFromCss };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DEFAULT_NO_OPTIONS_MESSAGES } from '../constants.js';
|
|
2
|
+
|
|
3
|
+
function isString(s) {
|
|
4
|
+
return Object.prototype.toString.call(s) === '[object String]';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function getEmptyMessage(_ref) {
|
|
8
|
+
let {
|
|
9
|
+
isLoading,
|
|
10
|
+
isNothingFound,
|
|
11
|
+
noOptionsMessage
|
|
12
|
+
} = _ref;
|
|
13
|
+
const {
|
|
14
|
+
noOptions,
|
|
15
|
+
nothingFound,
|
|
16
|
+
loading
|
|
17
|
+
} = isString(noOptionsMessage) ? { ...DEFAULT_NO_OPTIONS_MESSAGES,
|
|
18
|
+
noOptions: noOptionsMessage
|
|
19
|
+
} : { ...DEFAULT_NO_OPTIONS_MESSAGES,
|
|
20
|
+
...noOptionsMessage
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
if (isLoading) {
|
|
24
|
+
return loading;
|
|
25
|
+
} else if (isNothingFound) {
|
|
26
|
+
return nothingFound;
|
|
27
|
+
} else {
|
|
28
|
+
return noOptions;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { getEmptyMessage };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getTextFromNodes } from './get-text-from-nodes.js';
|
|
2
|
+
|
|
3
|
+
function getOptionValue(option) {
|
|
4
|
+
if (!option) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return typeof option.value === 'string' || typeof option.value === 'number' ? option.value : getTextFromNodes(option.label);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { getOptionValue };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { VIRTUAL_ITEMS_SECTION_KEY } from '../constants.js';
|
|
2
|
+
|
|
3
|
+
const getRealItemsCnt = state => {
|
|
4
|
+
// Count total number of items, ignoring virtual items
|
|
5
|
+
return [...state.collection].reduce((count, item) => {
|
|
6
|
+
if (item.type === 'section' && item.key !== VIRTUAL_ITEMS_SECTION_KEY) {
|
|
7
|
+
const sectionChildren = [...state.collection.getChildren(item.key)];
|
|
8
|
+
const hasHeading = item.rendered !== null && item.rendered !== undefined; // Count heading (if present) + all options in the section
|
|
9
|
+
|
|
10
|
+
return count + (hasHeading ? 1 : 0) + sectionChildren.length;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (item.type === 'item') {
|
|
14
|
+
return count + 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return count;
|
|
18
|
+
}, 0);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { getRealItemsCnt };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const getTextFromNodes = function (node) {
|
|
4
|
+
var _node$type;
|
|
5
|
+
|
|
6
|
+
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
7
|
+
|
|
8
|
+
if (typeof node === 'string' || typeof node === 'number') {
|
|
9
|
+
return node.toString();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (depth > 15) {
|
|
13
|
+
console.warn('Max depth reached while getting text from nodes');
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (Array.isArray(node)) {
|
|
18
|
+
return node.map(n => getTextFromNodes(n, depth + 1)).join('');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if ( /*#__PURE__*/React.isValidElement(node) && (node === null || node === void 0 || (_node$type = node.type) === null || _node$type === void 0 || (_node$type = _node$type.toString()) === null || _node$type === void 0 ? void 0 : _node$type.toLowerCase()) !== 'svg') {
|
|
22
|
+
return getTextFromNodes(node.props.children, depth + 1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return '';
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { getTextFromNodes };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { SelectOptionOrGroup, SelectOptionsGroup, NativeSelectOptionOrGroup, NativeSelectOption } from '../types';
|
|
2
|
+
export declare const isOptionAGroup: (optionOrGroup: SelectOptionOrGroup | NativeSelectOptionOrGroup) => optionOrGroup is SelectOptionsGroup | NativeSelectOption;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function throttle<A extends unknown[], R>(func: (...args: A) => R, wait: number): (...args: A) => R;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rescui/select",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1-RUI-280-Update-select-component-e516591ed.54+e516591ed",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "JetBrains",
|
|
@@ -16,13 +16,12 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@babel/runtime-corejs3": "^7.26.0",
|
|
19
|
-
"@rescui/
|
|
20
|
-
"@rescui/
|
|
21
|
-
"@rescui/
|
|
22
|
-
"@rescui/tag": "^0.13.4",
|
|
23
|
-
"@rescui/use-resize-observer": "^0.3.0",
|
|
19
|
+
"@rescui/form-field": "0.1.1-RUI-280-Update-select-component-e516591ed.54+e516591ed",
|
|
20
|
+
"@rescui/tag": "0.13.5-RUI-280-Update-select-component-e516591ed.54+e516591ed",
|
|
21
|
+
"@rescui/use-resize-observer": "0.3.1-RUI-280-Update-select-component-e516591ed.166+e516591ed",
|
|
24
22
|
"classnames": "^2.2.6",
|
|
25
|
-
"
|
|
23
|
+
"react-aria": "^3.47.0",
|
|
24
|
+
"react-stately": "^3.45.0"
|
|
26
25
|
},
|
|
27
26
|
"peerDependencies": {
|
|
28
27
|
"@rescui/ui-contexts": "^0.6.0",
|
|
@@ -30,10 +29,10 @@
|
|
|
30
29
|
"react": ">=16.8.0 <20"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
|
-
"@rescui/colors": "
|
|
34
|
-
"@rescui/scripts": "
|
|
35
|
-
"@rescui/typography": "
|
|
36
|
-
"@rescui/visual-regression": "
|
|
32
|
+
"@rescui/colors": "0.3.1-RUI-280-Update-select-component-e516591ed.54+e516591ed",
|
|
33
|
+
"@rescui/scripts": "0.5.1",
|
|
34
|
+
"@rescui/typography": "0.24.5-RUI-280-Update-select-component-e516591ed.54+e516591ed",
|
|
35
|
+
"@rescui/visual-regression": "0.1.4",
|
|
37
36
|
"sniffr": "^1.2.0"
|
|
38
37
|
},
|
|
39
38
|
"scripts": {
|
|
@@ -41,5 +40,5 @@
|
|
|
41
40
|
"build-pcss-api": "rescui-scripts build-pcss-api --file public-api.p.css"
|
|
42
41
|
},
|
|
43
42
|
"nx": {},
|
|
44
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "e516591ed7fc1a8ce27afc90612f7eea334c7d29"
|
|
45
44
|
}
|
package/lib/key-codes.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare const ARROW_UP = "ArrowUp";
|
|
2
|
-
export declare const ARROW_DOWN = "ArrowDown";
|
|
3
|
-
export declare const SPACE = " ";
|
|
4
|
-
export declare const ESCAPE = "Escape";
|
|
5
|
-
export declare const ENTER = "Enter";
|
|
6
|
-
export declare const TAB = "Tab";
|
|
7
|
-
export declare const BACKSPACE = "Backspace";
|
package/lib/key-codes.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
var styles = {
|
|
2
|
-
"sizeS": "_sizeS_18ip9hg_3",
|
|
3
|
-
"sizeM": "_sizeM_18ip9hg_6",
|
|
4
|
-
"sizeL": "_sizeL_18ip9hg_9",
|
|
5
|
-
"menu": "_menu_18ip9hg_13",
|
|
6
|
-
"menuSizeS": "_menuSizeS_18ip9hg_26",
|
|
7
|
-
"menuSizeM": "_menuSizeM_18ip9hg_30",
|
|
8
|
-
"menuSizeL": "_menuSizeL_18ip9hg_34",
|
|
9
|
-
"withGroupsLabel": "_withGroupsLabel_18ip9hg_40",
|
|
10
|
-
"lastOption": "_lastOption_18ip9hg_39",
|
|
11
|
-
"divider": "_divider_18ip9hg_45",
|
|
12
|
-
"checkIcon": "_checkIcon_18ip9hg_51",
|
|
13
|
-
"observable": "_observable_18ip9hg_56"
|
|
14
|
-
};
|
|
15
|
-
export { styles as default };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
var styles = {
|
|
2
|
-
"themeLight": "_themeLight_14qtra6_6",
|
|
3
|
-
"themeDark": "_themeDark_14qtra6_9",
|
|
4
|
-
"sizeS": "_sizeS_14qtra6_13",
|
|
5
|
-
"sizeM": "_sizeM_14qtra6_16",
|
|
6
|
-
"sizeL": "_sizeL_14qtra6_19",
|
|
7
|
-
"main": "_main_14qtra6_23",
|
|
8
|
-
"label": "_label_14qtra6_27",
|
|
9
|
-
"disabled": "_disabled_14qtra6_33",
|
|
10
|
-
"footer": "_footer_14qtra6_38",
|
|
11
|
-
"errorMessage": "_errorMessage_14qtra6_45",
|
|
12
|
-
"error": "_error_14qtra6_45",
|
|
13
|
-
"note": "_note_14qtra6_54"
|
|
14
|
-
};
|
|
15
|
-
export { styles as default };
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Theme } from '@rescui/ui-contexts';
|
|
3
|
-
import { SelectOptionOrGroup, SelectOption, SelectSize, SelectMode, NoOptionsMessage } from '../types';
|
|
4
|
-
export interface MultiselectProps {
|
|
5
|
-
/**
|
|
6
|
-
* Additional class name
|
|
7
|
-
*/
|
|
8
|
-
className?: string;
|
|
9
|
-
id?: string;
|
|
10
|
-
/**
|
|
11
|
-
* Array of options
|
|
12
|
-
*/
|
|
13
|
-
options: SelectOptionOrGroup[];
|
|
14
|
-
/**
|
|
15
|
-
* Is Multiselect preserve single string
|
|
16
|
-
*/
|
|
17
|
-
isSingleLine?: boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Is Multiselect supports clear the value
|
|
20
|
-
*/
|
|
21
|
-
isClearable?: boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Is Multiselect has been disabled
|
|
24
|
-
*/
|
|
25
|
-
isDisabled?: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Is loader displayed inside select
|
|
28
|
-
*/
|
|
29
|
-
isLoading?: boolean;
|
|
30
|
-
/**
|
|
31
|
-
* A hint to the user of what can be entered in the control
|
|
32
|
-
*/
|
|
33
|
-
placeholder?: string;
|
|
34
|
-
/**
|
|
35
|
-
* Size
|
|
36
|
-
*/
|
|
37
|
-
size?: SelectSize;
|
|
38
|
-
/**
|
|
39
|
-
* Appearance mode
|
|
40
|
-
*/
|
|
41
|
-
mode?: SelectMode;
|
|
42
|
-
/**
|
|
43
|
-
* Appearance theme
|
|
44
|
-
*/
|
|
45
|
-
theme?: Theme;
|
|
46
|
-
/**
|
|
47
|
-
* Value of the select
|
|
48
|
-
*/
|
|
49
|
-
value: SelectOption[];
|
|
50
|
-
/**
|
|
51
|
-
* Change value callback. `value => ...`
|
|
52
|
-
*/
|
|
53
|
-
onChange?: (newValue: SelectOption[]) => void;
|
|
54
|
-
/**
|
|
55
|
-
* Error state flag or React.ReactNode (use with forms)
|
|
56
|
-
*/
|
|
57
|
-
error?: boolean | React.ReactNode;
|
|
58
|
-
/**
|
|
59
|
-
* If `true`, there will be reserved a space for a 1-line error message. Subsequent lines will be placed below normally.
|
|
60
|
-
* If `false`, there will be no reservation.
|
|
61
|
-
*/
|
|
62
|
-
reserveErrorLine?: boolean;
|
|
63
|
-
/**
|
|
64
|
-
* Label element upper then Multiselect element (use with forms)
|
|
65
|
-
*/
|
|
66
|
-
label?: React.ReactNode;
|
|
67
|
-
/**
|
|
68
|
-
* Placement of dropdown element
|
|
69
|
-
*/
|
|
70
|
-
placement?: 'auto-start' | 'auto' | 'auto-end' | 'top-start' | 'top' | 'top-end' | 'right-start' | 'right' | 'right-end' | 'bottom-end' | 'bottom' | 'bottom-start' | 'left-end' | 'left' | 'left-start';
|
|
71
|
-
/**
|
|
72
|
-
* Note element below then Multiselect element (use with forms)
|
|
73
|
-
*/
|
|
74
|
-
note?: React.ReactNode;
|
|
75
|
-
/**
|
|
76
|
-
* Text to display when there are no options
|
|
77
|
-
*/
|
|
78
|
-
noOptionsMessage?: NoOptionsMessage;
|
|
79
|
-
/**
|
|
80
|
-
* Input name attribute
|
|
81
|
-
*/
|
|
82
|
-
name?: string;
|
|
83
|
-
boldLabel?: boolean;
|
|
84
|
-
}
|
|
85
|
-
declare const Multiselect: React.FC<MultiselectProps>;
|
|
86
|
-
export default Multiselect;
|