@rescui/select 0.15.1-RUI-280-Update-select-component-e516591ed.54 → 0.15.1-RUI-280-Update-select-component-downshift-cd2a98813.66

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/lib/_virtual/index.css.js +12 -12
  2. package/lib/constants.d.ts +0 -1
  3. package/lib/constants.js +1 -2
  4. package/lib/hooks/use-a11y.d.ts +29 -0
  5. package/lib/hooks/use-a11y.js +53 -0
  6. package/lib/hooks/use-backward-compatible-id.d.ts +4 -0
  7. package/lib/hooks/use-backward-compatible-id.js +14 -0
  8. package/lib/hooks/use-label-focus.d.ts +1 -3
  9. package/lib/hooks/use-label-focus.js +3 -9
  10. package/lib/hooks/use-multi-handlers.d.ts +11 -0
  11. package/lib/hooks/use-multi-handlers.js +48 -0
  12. package/lib/hooks/use-options.d.ts +13 -0
  13. package/lib/hooks/use-options.js +89 -0
  14. package/lib/index.css +323 -371
  15. package/lib/multiselect.d.ts +3 -29
  16. package/lib/multiselect.js +249 -171
  17. package/lib/native-select.js +67 -44
  18. package/lib/parts/hidden-select.d.ts +13 -0
  19. package/lib/parts/hidden-select.js +45 -0
  20. package/lib/parts/icons.d.ts +3 -1
  21. package/lib/parts/icons.js +11 -14
  22. package/lib/parts/list-box.d.ts +7 -15
  23. package/lib/parts/list-box.js +50 -80
  24. package/lib/parts/multi-trigger.d.ts +5 -4
  25. package/lib/parts/multi-trigger.js +27 -15
  26. package/lib/parts/native-select-trigger.d.ts +6 -8
  27. package/lib/parts/native-select-trigger.js +14 -23
  28. package/lib/select-basic.d.ts +2 -2
  29. package/lib/select-basic.js +162 -95
  30. package/lib/select-searchable.d.ts +2 -2
  31. package/lib/select-searchable.js +209 -119
  32. package/lib/select.d.ts +1 -1
  33. package/lib/select.js +38 -31
  34. package/lib/styles/common.p.module.css.js +25 -24
  35. package/lib/styles/form-trigger.p.module.css.js +12 -12
  36. package/lib/styles/list-box.p.module.css.js +11 -13
  37. package/lib/styles/native-select-trigger.p.module.css.js +15 -14
  38. package/lib/styles/native-select.p.module.css.js +6 -6
  39. package/lib/types.d.ts +26 -26
  40. package/lib/utils/get-real-items-cnt.d.ts +2 -2
  41. package/lib/utils/get-real-items-cnt.js +8 -10
  42. package/lib/utils/item-to-string.d.ts +2 -0
  43. package/lib/utils/item-to-string.js +7 -0
  44. package/lib/utils/merge-props.d.ts +29 -0
  45. package/lib/utils/merge-props.js +106 -0
  46. package/package.json +12 -8
  47. package/lib/hooks/use-css-context-transfer.d.ts +0 -14
  48. package/lib/hooks/use-css-context-transfer.js +0 -40
  49. package/lib/hooks/use-multi-option-serialization.d.ts +0 -10
  50. package/lib/hooks/use-multi-option-serialization.js +0 -82
  51. package/lib/hooks/use-observable-force-rerender.d.ts +0 -2
  52. package/lib/hooks/use-observable-force-rerender.js +0 -16
  53. package/lib/hooks/use-option-serialization.d.ts +0 -10
  54. package/lib/hooks/use-option-serialization.js +0 -59
  55. package/lib/parts/popover.d.ts +0 -12
  56. package/lib/parts/popover.js +0 -62
  57. package/lib/parts/popup-content.d.ts +0 -19
  58. package/lib/parts/popup-content.js +0 -76
  59. package/lib/styles/popover.p.module.css.js +0 -10
  60. package/lib/utils/convert-options.d.ts +0 -3
  61. package/lib/utils/convert-options.js +0 -52
  62. package/lib/utils/convert-placement.d.ts +0 -3
  63. package/lib/utils/convert-placement.js +0 -22
  64. package/lib/utils/css-vars-utils.d.ts +0 -3
  65. package/lib/utils/css-vars-utils.js +0 -20
package/lib/select.d.ts CHANGED
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import type { SelectProps, SelectOption, SelectOptionOrGroup } from './types';
4
4
  export declare const Select: {
5
- ({ options, size, mode, theme: themeFromProps, className, style, value, onChange, placeholder, isClearable, isLoading, isDisabled, isSearchable, noOptionsMessage, error, placement, boldLabel, reserveErrorLine, note, maxVisibleItems, ...restProps }: SelectProps): JSX.Element;
5
+ ({ options, size, mode, theme: themeFromProps, className, style, value, onChange, placeholder, isClearable, isLoading, isDisabled, isSearchable, noOptionsMessage, error, placement, boldLabel, reserveErrorLine, note, maxVisibleItems, id, ...restProps }: SelectProps): JSX.Element;
6
6
  propTypes: {
7
7
  className: PropTypes.Requireable<string>;
8
8
  style: PropTypes.Requireable<object>;
package/lib/select.js CHANGED
@@ -1,15 +1,26 @@
1
1
  "use client";
2
2
  import React from 'react';
3
- import { useThemeWithUndefined } from '@rescui/ui-contexts';
4
3
  import PropTypes from 'prop-types';
5
4
  import { ErrorMessage } from '@rescui/form-field';
5
+ import cn from 'classnames';
6
+ import { useThemeWithUndefined } from '@rescui/ui-contexts';
6
7
  import { optionType, optionsGroupType, noOptionsMessageType } from './common-prop-types.js';
7
- import { useOptionSerialization } from './hooks/use-option-serialization.js';
8
- import { convertOptions } from './utils/convert-options.js';
9
- import { convertPlacement } from './utils/convert-placement.js';
10
- import { getOptionValue } from './utils/get-option-value.js';
11
8
  import { SelectBasic } from './select-basic.js';
12
9
  import { SelectSearchable } from './select-searchable.js';
10
+ import styles from './styles/common.p.module.css.js';
11
+ const THEME_STYLES = {
12
+ light: styles.themeLight,
13
+ dark: styles.themeDark
14
+ };
15
+ const SIZE_STYLES = {
16
+ s: styles.sizeS,
17
+ m: styles.sizeM,
18
+ l: styles.sizeL
19
+ };
20
+ const MODE_STYLES = {
21
+ classic: styles.classic,
22
+ rock: styles.rock
23
+ };
13
24
 
14
25
  const Select = _ref => {
15
26
  let {
@@ -33,42 +44,38 @@ const Select = _ref => {
33
44
  reserveErrorLine = false,
34
45
  note,
35
46
  maxVisibleItems = 5,
47
+ id,
36
48
  ...restProps
37
49
  } = _ref;
38
50
  const theme = useThemeWithUndefined(themeFromProps);
39
- const {
40
- selectedKey,
41
- findOptionByKey,
42
- virtualOption
43
- } = useOptionSerialization(options, value);
44
-
45
- const handleSelectionChange = key => {
46
- const option = findOptionByKey(key);
47
- onChange === null || onChange === void 0 || onChange(option);
48
- };
49
-
50
51
  const InnerSingleComponent = isSearchable ? SelectSearchable : SelectBasic;
51
- return /*#__PURE__*/React.createElement(InnerSingleComponent, { ...restProps,
52
- isDisabled: isDisabled,
53
- value: selectedKey,
54
- onChange: handleSelectionChange,
55
- placeholder: placeholder,
56
- isClearable: isClearable,
57
- isLoading: isLoading,
58
- className: className,
52
+ return /*#__PURE__*/React.createElement("div", {
53
+ className: cn(className, styles.root, THEME_STYLES[theme], SIZE_STYLES[size], MODE_STYLES[mode], isDisabled ? styles.disabled : styles.enabled, Boolean(error) && styles.error),
54
+ id: id,
59
55
  style: style,
56
+ "data-test": "select"
57
+ }, /*#__PURE__*/React.createElement(InnerSingleComponent, { ...restProps,
58
+ options: options,
60
59
  size: size,
61
60
  mode: mode,
62
61
  theme: theme,
63
- errorMessage: error,
64
- placement: convertPlacement(placement),
62
+ className: className,
63
+ id: id,
64
+ style: style,
65
+ value: value,
66
+ onChange: onChange,
67
+ placeholder: placeholder,
68
+ isClearable: isClearable,
69
+ isLoading: isLoading,
70
+ isDisabled: isDisabled,
71
+ noOptionsMessage: noOptionsMessage,
72
+ error: error,
73
+ placement: placement,
65
74
  boldLabel: boldLabel,
66
75
  reserveErrorLine: reserveErrorLine,
67
- description: note,
68
- noOptionsMessage: noOptionsMessage,
69
- maxVisibleItems: maxVisibleItems,
70
- disabledKeys: virtualOption ? [getOptionValue(virtualOption)] : []
71
- }, convertOptions(options, [virtualOption].filter(Boolean)));
76
+ note: note,
77
+ maxVisibleItems: maxVisibleItems
78
+ }));
72
79
  };
73
80
 
74
81
  Select.propTypes = {
@@ -1,27 +1,28 @@
1
1
  var styles = {
2
- "themeLight": "_themeLight_60u4bs_6",
3
- "themeDark": "_themeDark_60u4bs_9",
4
- "sizeS": "_sizeS_60u4bs_13",
5
- "sizeM": "_sizeM_60u4bs_16",
6
- "sizeL": "_sizeL_60u4bs_19",
7
- "classic": "_classic_60u4bs_23",
8
- "rock": "_rock_60u4bs_26",
9
- "root": "_root_60u4bs_30",
10
- "trigger": "_trigger_60u4bs_36",
11
- "error": "_error_60u4bs_69",
12
- "enabled": "_enabled_60u4bs_74",
13
- "disabled": "_disabled_60u4bs_78",
14
- "canBeMultiline": "_canBeMultiline_60u4bs_119",
15
- "iconsWrapper": "_iconsWrapper_60u4bs_123",
16
- "triggerText": "_triggerText_60u4bs_138",
17
- "searchInput": "_searchInput_60u4bs_144",
18
- "labelNotSelected": "_labelNotSelected_60u4bs_188",
19
- "multi": "_multi_60u4bs_202",
20
- "tagsContainer": "_tagsContainer_60u4bs_218",
21
- "tag": "_tag_60u4bs_218",
22
- "filledTag": "_filledTag_60u4bs_240",
23
- "toggle": "_toggle_60u4bs_248",
24
- "icon": "_icon_60u4bs_123",
25
- "clearIcon": "_clearIcon_60u4bs_315"
2
+ "themeLight": "_themeLight_kb0k7d_6",
3
+ "themeDark": "_themeDark_kb0k7d_9",
4
+ "sizeS": "_sizeS_kb0k7d_13",
5
+ "sizeM": "_sizeM_kb0k7d_16",
6
+ "sizeL": "_sizeL_kb0k7d_19",
7
+ "classic": "_classic_kb0k7d_23",
8
+ "rock": "_rock_kb0k7d_26",
9
+ "root": "_root_kb0k7d_30",
10
+ "trigger": "_trigger_kb0k7d_36",
11
+ "error": "_error_kb0k7d_69",
12
+ "enabled": "_enabled_kb0k7d_74",
13
+ "disabled": "_disabled_kb0k7d_78",
14
+ "canBeMultiline": "_canBeMultiline_kb0k7d_115",
15
+ "iconsWrapper": "_iconsWrapper_kb0k7d_119",
16
+ "triggerText": "_triggerText_kb0k7d_134",
17
+ "searchInput": "_searchInput_kb0k7d_140",
18
+ "labelNotSelected": "_labelNotSelected_kb0k7d_184",
19
+ "multi": "_multi_kb0k7d_198",
20
+ "tagsContainer": "_tagsContainer_kb0k7d_214",
21
+ "tag": "_tag_kb0k7d_214",
22
+ "filledTag": "_filledTag_kb0k7d_236",
23
+ "toggle": "_toggle_kb0k7d_244",
24
+ "icon": "_icon_kb0k7d_119",
25
+ "clearIcon": "_clearIcon_kb0k7d_311",
26
+ "hiddenSelect": "_hiddenSelect_kb0k7d_368"
26
27
  };
27
28
  export { styles as default };
@@ -1,15 +1,15 @@
1
1
  var styles = {
2
- "themeLight": "_themeLight_1k683lb_6",
3
- "themeDark": "_themeDark_1k683lb_9",
4
- "sizeS": "_sizeS_1k683lb_13",
5
- "sizeM": "_sizeM_1k683lb_16",
6
- "sizeL": "_sizeL_1k683lb_19",
7
- "main": "_main_1k683lb_23",
8
- "label": "_label_1k683lb_27",
9
- "disabled": "_disabled_1k683lb_33",
10
- "footer": "_footer_1k683lb_38",
11
- "errorMessage": "_errorMessage_1k683lb_45",
12
- "error": "_error_1k683lb_45",
13
- "note": "_note_1k683lb_54"
2
+ "themeLight": "_themeLight_lkq6p4_6",
3
+ "themeDark": "_themeDark_lkq6p4_9",
4
+ "sizeS": "_sizeS_lkq6p4_13",
5
+ "sizeM": "_sizeM_lkq6p4_16",
6
+ "sizeL": "_sizeL_lkq6p4_19",
7
+ "main": "_main_lkq6p4_23",
8
+ "label": "_label_lkq6p4_27",
9
+ "disabled": "_disabled_lkq6p4_33",
10
+ "footer": "_footer_lkq6p4_38",
11
+ "errorMessage": "_errorMessage_lkq6p4_45",
12
+ "error": "_error_lkq6p4_45",
13
+ "note": "_note_lkq6p4_54"
14
14
  };
15
15
  export { styles as default };
@@ -1,16 +1,14 @@
1
1
  var styles = {
2
- "sizeS": "_sizeS_57zbb_6",
3
- "sizeM": "_sizeM_57zbb_9",
4
- "sizeL": "_sizeL_57zbb_12",
5
- "modeClassic": "_modeClassic_57zbb_16",
6
- "modeRock": "_modeRock_57zbb_19",
7
- "listBox": "_listBox_57zbb_23",
8
- "item": "_item_57zbb_36",
9
- "selected": "_selected_57zbb_82",
10
- "disabled": "_disabled_57zbb_93",
11
- "checkIcon": "_checkIcon_57zbb_100",
12
- "visible": "_visible_57zbb_107",
13
- "divider": "_divider_57zbb_114",
14
- "groupHeader": "_groupHeader_57zbb_128"
2
+ "sizeS": "_sizeS_nz7l8y_6",
3
+ "sizeM": "_sizeM_nz7l8y_9",
4
+ "sizeL": "_sizeL_nz7l8y_12",
5
+ "listBox": "_listBox_nz7l8y_16",
6
+ "item": "_item_nz7l8y_30",
7
+ "selected": "_selected_nz7l8y_76",
8
+ "disabled": "_disabled_nz7l8y_87",
9
+ "checkIcon": "_checkIcon_nz7l8y_94",
10
+ "visible": "_visible_nz7l8y_101",
11
+ "divider": "_divider_nz7l8y_108",
12
+ "groupHeader": "_groupHeader_nz7l8y_122"
15
13
  };
16
14
  export { styles as default };
@@ -1,17 +1,18 @@
1
1
  var styles = {
2
- "themeLight": "_themeLight_1lf70g_6",
3
- "themeDark": "_themeDark_1lf70g_9",
4
- "sizeS": "_sizeS_1lf70g_13",
5
- "sizeM": "_sizeM_1lf70g_16",
6
- "sizeL": "_sizeL_1lf70g_19",
7
- "trigger": "_trigger_1lf70g_23",
8
- "error": "_error_1lf70g_61",
9
- "enabled": "_enabled_1lf70g_66",
10
- "disabled": "_disabled_1lf70g_70",
11
- "iconsWrapper": "_iconsWrapper_1lf70g_103",
12
- "triggerText": "_triggerText_1lf70g_118",
13
- "labelNotSelected": "_labelNotSelected_1lf70g_144",
14
- "toggle": "_toggle_1lf70g_155",
15
- "icon": "_icon_1lf70g_103"
2
+ "themeLight": "_themeLight_3v0lc_6",
3
+ "themeDark": "_themeDark_3v0lc_9",
4
+ "sizeS": "_sizeS_3v0lc_13",
5
+ "sizeM": "_sizeM_3v0lc_16",
6
+ "sizeL": "_sizeL_3v0lc_19",
7
+ "trigger": "_trigger_3v0lc_23",
8
+ "error": "_error_3v0lc_61",
9
+ "enabled": "_enabled_3v0lc_66",
10
+ "disabled": "_disabled_3v0lc_70",
11
+ "iconsWrapper": "_iconsWrapper_3v0lc_104",
12
+ "triggerText": "_triggerText_3v0lc_119",
13
+ "labelNotSelected": "_labelNotSelected_3v0lc_145",
14
+ "toggle": "_toggle_3v0lc_156",
15
+ "icon": "_icon_3v0lc_104",
16
+ "clearIcon": "_clearIcon_3v0lc_218"
16
17
  };
17
18
  export { styles as default };
@@ -1,9 +1,9 @@
1
1
  var styles = {
2
- "sizeS": "_sizeS_19uvt4l_6",
3
- "sizeM": "_sizeM_19uvt4l_9",
4
- "sizeL": "_sizeL_19uvt4l_12",
5
- "main": "_main_19uvt4l_16",
6
- "wrapper": "_wrapper_19uvt4l_20",
7
- "select": "_select_19uvt4l_24"
2
+ "sizeS": "_sizeS_ngrfhd_6",
3
+ "sizeM": "_sizeM_ngrfhd_9",
4
+ "sizeL": "_sizeL_ngrfhd_12",
5
+ "main": "_main_ngrfhd_16",
6
+ "wrapper": "_wrapper_ngrfhd_20",
7
+ "select": "_select_ngrfhd_24"
8
8
  };
9
9
  export { styles as default };
package/lib/types.d.ts CHANGED
@@ -1,14 +1,8 @@
1
1
  import React from 'react';
2
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';
3
+ import type { UseSelectPropGetters } from 'downshift';
4
+ export declare type Key = string | number;
10
5
  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'];
12
6
  export declare type SelectSize = 'l' | 'm' | 's';
13
7
  export declare type SelectMode = 'classic' | 'rock';
14
8
  export declare type SelectOption = {
@@ -21,6 +15,27 @@ export declare type SelectOptionsGroup = {
21
15
  };
22
16
  export declare type SelectOptionOrGroup = SelectOption | SelectOptionsGroup;
23
17
  export declare type SelectOptions = SelectOptionOrGroup[];
18
+ export declare type ListBoxOptionItem = SelectOption & {
19
+ index: number;
20
+ type: 'option';
21
+ key: Key;
22
+ disabled?: boolean;
23
+ };
24
+ export declare type ListBoxGroupItem = Omit<SelectOptionsGroup, 'options'> & {
25
+ options: ListBoxOptionItem[];
26
+ type: 'group';
27
+ key: Key;
28
+ };
29
+ export declare type ListBoxItem = ListBoxOptionItem | ListBoxGroupItem;
30
+ export declare type ListBoxItems = ListBoxItem[];
31
+ export declare type ListBoxState = {
32
+ menuProps: ReturnType<UseSelectPropGetters<SelectOption>['getMenuProps']>;
33
+ getItemProps: UseSelectPropGetters<SelectOption>['getItemProps'];
34
+ selectionMode: 'single' | 'multiple';
35
+ highlightedIndex: number;
36
+ selectedMap: Map<Key, SelectOption>;
37
+ menuRef?: React.RefObject<HTMLUListElement>;
38
+ };
24
39
  export declare type NativeSelectOption = {
25
40
  label: string;
26
41
  value?: Key;
@@ -165,6 +180,7 @@ export declare type NativeSelectProps = {
165
180
  placeholder?: string;
166
181
  isLoading?: boolean;
167
182
  isDisabled?: boolean;
183
+ isClearable?: boolean;
168
184
  trigger?: (props: TriggerFuncProps) => React.ReactNode;
169
185
  label?: React.ReactNode;
170
186
  note?: React.ReactNode;
@@ -177,21 +193,5 @@ export declare type NativeSelectProps = {
177
193
  noOptionsMessage?: NoOptionsMessage;
178
194
  name?: string;
179
195
  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>;
196
+ };
197
+ export declare type InnerSingleComponentProps = Omit<SelectProps, 'isSearchable'>;
@@ -1,2 +1,2 @@
1
- import type { ListState } from 'react-stately';
2
- export declare const getRealItemsCnt: <T extends object>(state: ListState<T>) => number;
1
+ import { ListBoxItem } from '../types';
2
+ export declare const getRealItemsCnt: (items: ListBoxItem[]) => number;
@@ -1,16 +1,14 @@
1
- import { VIRTUAL_ITEMS_SECTION_KEY } from '../constants.js';
1
+ const getRealItemsCnt = items => {
2
+ // Count total number of items
3
+ return items.reduce((count, item) => {
4
+ if (item.type === 'group') {
5
+ const groupOptions = item.options;
6
+ const hasHeading = item.label !== null && item.label !== undefined; // Count heading (if present) + all options in the section
2
7
 
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;
8
+ return count + (hasHeading ? 1 : 0) + groupOptions.length;
11
9
  }
12
10
 
13
- if (item.type === 'item') {
11
+ if (item.type === 'option') {
14
12
  return count + 1;
15
13
  }
16
14
 
@@ -0,0 +1,2 @@
1
+ import type { SelectOption } from '../types';
2
+ export declare function itemToString(item: SelectOption): string;
@@ -0,0 +1,7 @@
1
+ import { getTextFromNodes } from './get-text-from-nodes.js';
2
+
3
+ function itemToString(item) {
4
+ return item ? getTextFromNodes(item.label) : '';
5
+ }
6
+
7
+ export { itemToString };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copied from react-aria repo
3
+ * @see https://github.com/adobe/react-spectrum/blob/main/packages/react-aria/src/utils/mergeProps.ts
4
+ */
5
+ import type { MutableRefObject, RefCallback } from 'react';
6
+ /**
7
+ * Merges multiple refs into one. Works with either callback or object refs.
8
+ */
9
+ export declare function mergeRefs<T>(...refs: Array<RefCallback<T> | MutableRefObject<T> | null | undefined>): RefCallback<T> | MutableRefObject<T>;
10
+ export declare function chain(...callbacks: any[]): (...args: any[]) => void;
11
+ interface Props {
12
+ [key: string]: any;
13
+ }
14
+ declare type PropsArg = Props | null | undefined;
15
+ declare type TupleTypes<T> = {
16
+ [P in keyof T]: T[P];
17
+ } extends {
18
+ [key: number]: infer V;
19
+ } ? NullToObject<V> : never;
20
+ declare type NullToObject<T> = T extends null | undefined ? object : T;
21
+ declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
22
+ /**
23
+ * Merges multiple props objects together. Event handlers are chained,
24
+ * classNames are combined, ids are deduplicated, and refs are merged.
25
+ * For all other props, the last prop object overrides all previous ones.
26
+ * @param args - Multiple sets of props to merge together.
27
+ */
28
+ export declare function mergeProps<T extends PropsArg[]>(...args: T): UnionToIntersection<TupleTypes<T>>;
29
+ export {};
@@ -0,0 +1,106 @@
1
+ import cn from 'classnames';
2
+ /* eslint-disable @typescript-eslint/no-explicit-any,consistent-return */
3
+
4
+ function setRef(ref, value) {
5
+ if (typeof ref === 'function') {
6
+ return ref(value);
7
+ } else if (ref !== null) {
8
+ ref.current = value;
9
+ }
10
+ }
11
+ /**
12
+ * Merges multiple refs into one. Works with either callback or object refs.
13
+ */
14
+
15
+
16
+ function mergeRefs() {
17
+ for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {
18
+ refs[_key] = arguments[_key];
19
+ }
20
+
21
+ if (refs.length === 1 && refs[0]) {
22
+ return refs[0];
23
+ }
24
+
25
+ return value => {
26
+ let hasCleanup = false;
27
+ const cleanups = refs.map(ref => {
28
+ const cleanup = setRef(ref, value);
29
+ hasCleanup = hasCleanup || typeof cleanup === 'function';
30
+ return cleanup;
31
+ });
32
+
33
+ if (hasCleanup) {
34
+ return () => {
35
+ cleanups.forEach((cleanup, i) => {
36
+ if (typeof cleanup === 'function') {
37
+ cleanup();
38
+ } else {
39
+ setRef(refs[i], null);
40
+ }
41
+ });
42
+ };
43
+ }
44
+ };
45
+ }
46
+
47
+ function chain() {
48
+ for (var _len2 = arguments.length, callbacks = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
49
+ callbacks[_key2] = arguments[_key2];
50
+ }
51
+
52
+ return function () {
53
+ for (const callback of callbacks) {
54
+ if (typeof callback === 'function') {
55
+ callback(...arguments);
56
+ }
57
+ }
58
+ };
59
+ }
60
+ /**
61
+ * Merges multiple props objects together. Event handlers are chained,
62
+ * classNames are combined, ids are deduplicated, and refs are merged.
63
+ * For all other props, the last prop object overrides all previous ones.
64
+ * @param args - Multiple sets of props to merge together.
65
+ */
66
+ // eslint-disable-next-line complexity
67
+
68
+
69
+ function mergeProps() {
70
+ // Start with a base clone of the first argument. This is a lot faster than starting
71
+ // with an empty object and adding properties as we go.
72
+ const result = { ...(arguments.length <= 0 ? undefined : arguments[0])
73
+ };
74
+
75
+ for (let i = 1; i < arguments.length; i++) {
76
+ const props = i < 0 || arguments.length <= i ? undefined : arguments[i];
77
+
78
+ for (const key in props) {
79
+ if (!props.hasOwnProperty(key)) {
80
+ continue;
81
+ }
82
+
83
+ const a = result[key];
84
+ const b = props[key]; // Chain events
85
+
86
+ if (typeof a === 'function' && typeof b === 'function' && // This is a lot faster than a regex.
87
+ key[0] === 'o' && key[1] === 'n' && key.charCodeAt(2) >=
88
+ /* 'A' */
89
+ 65 && key.charCodeAt(2) <=
90
+ /* 'Z' */
91
+ 90) {
92
+ result[key] = chain(a, b); // Merge classnames, sometimes classNames are empty string which eval to false, so we just need to do a type check
93
+ } else if (key === 'className' && typeof a === 'string' && typeof b === 'string') {
94
+ result[key] = cn(a, b);
95
+ } else if (key === 'ref' && a && b) {
96
+ result.ref = mergeRefs(a, b); // Override others
97
+ } else {
98
+ result[key] = b !== undefined ? b : a;
99
+ }
100
+ }
101
+ }
102
+
103
+ return result;
104
+ }
105
+
106
+ export { chain, mergeProps, mergeRefs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rescui/select",
3
- "version": "0.15.1-RUI-280-Update-select-component-e516591ed.54+e516591ed",
3
+ "version": "0.15.1-RUI-280-Update-select-component-downshift-cd2a98813.66+cd2a98813",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "author": "JetBrains",
@@ -16,12 +16,16 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@babel/runtime-corejs3": "^7.26.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",
19
+ "@react-aria/focus": "^3.22.0",
20
+ "@rescui/dropdown": "0.9.5-RUI-280-Update-select-component-downshift-cd2a98813.66+cd2a98813",
21
+ "@rescui/form-field": "0.1.1-RUI-280-Update-select-component-downshift-cd2a98813.66+cd2a98813",
22
+ "@rescui/tag": "0.13.5-RUI-280-Update-select-component-downshift-cd2a98813.66+cd2a98813",
23
+ "@rescui/use-resize-observer": "0.3.1-RUI-280-Update-select-component-downshift-cd2a98813.178+cd2a98813",
22
24
  "classnames": "^2.2.6",
25
+ "downshift": "^9.3.2",
23
26
  "react-aria": "^3.47.0",
24
- "react-stately": "^3.45.0"
27
+ "react-stately": "^3.45.0",
28
+ "scroll-into-view-if-needed": "3.1.0"
25
29
  },
26
30
  "peerDependencies": {
27
31
  "@rescui/ui-contexts": "^0.6.0",
@@ -29,9 +33,9 @@
29
33
  "react": ">=16.8.0 <20"
30
34
  },
31
35
  "devDependencies": {
32
- "@rescui/colors": "0.3.1-RUI-280-Update-select-component-e516591ed.54+e516591ed",
36
+ "@rescui/colors": "0.3.1-RUI-280-Update-select-component-downshift-cd2a98813.66+cd2a98813",
33
37
  "@rescui/scripts": "0.5.1",
34
- "@rescui/typography": "0.24.5-RUI-280-Update-select-component-e516591ed.54+e516591ed",
38
+ "@rescui/typography": "0.24.5-RUI-280-Update-select-component-downshift-cd2a98813.66+cd2a98813",
35
39
  "@rescui/visual-regression": "0.1.4",
36
40
  "sniffr": "^1.2.0"
37
41
  },
@@ -40,5 +44,5 @@
40
44
  "build-pcss-api": "rescui-scripts build-pcss-api --file public-api.p.css"
41
45
  },
42
46
  "nx": {},
43
- "gitHead": "e516591ed7fc1a8ce27afc90612f7eea334c7d29"
47
+ "gitHead": "cd2a98813d37db8b46393317febfce4e91592516"
44
48
  }
@@ -1,14 +0,0 @@
1
- import React from 'react';
2
- import { type Theme } from '@rescui/ui-contexts';
3
- import type { SelectSize } from '../types';
4
- export declare type useCssContextTransferArgs = {
5
- triggerRef: React.RefObject<HTMLElement>;
6
- isOpen: boolean;
7
- themeFromProps: Theme;
8
- sizeFromProps: SelectSize;
9
- };
10
- export declare const useCssContextTransfer: ({ triggerRef, isOpen, themeFromProps, sizeFromProps }: useCssContextTransferArgs) => {
11
- size: SelectSize;
12
- theme: Theme;
13
- primaryColors: Record<string, string>;
14
- };
@@ -1,40 +0,0 @@
1
- import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
2
- import { useContext } from 'react';
3
- import { ThemeContext } from '@rescui/ui-contexts';
4
- import { extractThemeFromCss, extractPrimaryColors } from '../utils/css-vars-utils.js';
5
-
6
- const useCssContextTransfer = _ref => {
7
- let {
8
- triggerRef,
9
- isOpen,
10
- themeFromProps,
11
- sizeFromProps
12
- } = _ref;
13
- let sizeFromCss = null;
14
- let themeFromCss = 'light';
15
- let primaryColors = {};
16
-
17
- if (triggerRef.current && isOpen) {
18
- var _context;
19
-
20
- const triggerFormWrapperStyles = getComputedStyle(triggerRef.current);
21
- const rawSizeFromCss = triggerFormWrapperStyles.getPropertyValue('--_rs-select-size');
22
- sizeFromCss = _includesInstanceProperty(_context = ['s', 'm', 'l']).call(_context, rawSizeFromCss) ? rawSizeFromCss : null;
23
- themeFromCss = extractThemeFromCss(triggerFormWrapperStyles);
24
- primaryColors = extractPrimaryColors(triggerFormWrapperStyles);
25
- }
26
-
27
- const size = sizeFromCss || sizeFromProps;
28
- const {
29
- theme: themeFromContext,
30
- noProvider
31
- } = useContext(ThemeContext);
32
- const theme = themeFromProps || (noProvider ? themeFromCss : themeFromContext);
33
- return {
34
- size,
35
- theme,
36
- primaryColors
37
- };
38
- };
39
-
40
- export { useCssContextTransfer };
@@ -1,10 +0,0 @@
1
- import type { SelectOption, SelectOptionOrGroup, Key } from '../types';
2
- export declare function useMultiOptionSerialization(options: SelectOptionOrGroup[], value?: SelectOption[] | null): {
3
- optionsMap: Map<Key, {
4
- option: SelectOption;
5
- isVirtual: boolean;
6
- }>;
7
- selectedKeys: Key[];
8
- findOptionsByKeys: (keys: Key[]) => SelectOption[];
9
- virtualOptions: SelectOption[];
10
- };