@rescui/select 0.15.1 → 0.16.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.
Files changed (95) hide show
  1. package/lib/_virtual/index.css.js +12 -12
  2. package/lib/common-prop-types.d.ts +8 -14
  3. package/lib/common-prop-types.js +4 -3
  4. package/lib/constants.d.ts +6 -0
  5. package/lib/constants.js +7 -0
  6. package/lib/hooks/use-a11y.d.ts +30 -0
  7. package/lib/hooks/use-a11y.js +56 -0
  8. package/lib/hooks/use-actual-size-from-css.d.ts +10 -0
  9. package/lib/hooks/use-actual-size-from-css.js +27 -0
  10. package/lib/hooks/use-focus.d.ts +10 -0
  11. package/lib/hooks/use-focus.js +17 -0
  12. package/lib/hooks/use-hover.d.ts +10 -0
  13. package/lib/hooks/use-hover.js +17 -0
  14. package/lib/hooks/use-label-focus.d.ts +9 -0
  15. package/lib/hooks/use-label-focus.js +22 -0
  16. package/lib/hooks/use-multi-handlers.d.ts +11 -0
  17. package/lib/hooks/use-multi-handlers.js +44 -0
  18. package/lib/hooks/use-options.d.ts +14 -0
  19. package/lib/hooks/use-options.js +90 -0
  20. package/lib/hooks/use-primary-contrast-css-var-transfer.d.ts +11 -0
  21. package/lib/hooks/use-primary-contrast-css-var-transfer.js +29 -0
  22. package/lib/hooks/use-safe-id.d.ts +6 -0
  23. package/lib/hooks/use-safe-id.js +15 -0
  24. package/lib/index.css +713 -304
  25. package/lib/index.d.ts +4 -6
  26. package/lib/index.js +3 -3
  27. package/lib/multiselect.d.ts +3 -0
  28. package/lib/multiselect.js +308 -0
  29. package/lib/native-select.d.ts +4 -0
  30. package/lib/native-select.js +208 -0
  31. package/lib/parts/foldable.js +5 -7
  32. package/lib/parts/form-trigger-wrapper.d.ts +7 -7
  33. package/lib/parts/form-trigger-wrapper.js +16 -34
  34. package/lib/parts/hidden-select.d.ts +13 -0
  35. package/lib/parts/hidden-select.js +45 -0
  36. package/lib/parts/icons.d.ts +17 -0
  37. package/lib/parts/icons.js +69 -0
  38. package/lib/parts/list-box.d.ts +13 -0
  39. package/lib/parts/list-box.js +120 -0
  40. package/lib/parts/multi-trigger.d.ts +12 -0
  41. package/lib/parts/multi-trigger.js +70 -0
  42. package/lib/parts/native-select-options-with-groups.d.ts +8 -0
  43. package/lib/parts/native-select-options-with-groups.js +76 -0
  44. package/lib/parts/popup-content.d.ts +20 -0
  45. package/lib/parts/popup-content.js +68 -0
  46. package/lib/public-api.p.css +543 -307
  47. package/lib/public-api.pcss +543 -307
  48. package/lib/select-basic.d.ts +3 -0
  49. package/lib/select-basic.js +204 -0
  50. package/lib/select-searchable.d.ts +3 -0
  51. package/lib/select-searchable.js +245 -0
  52. package/lib/select.d.ts +27 -91
  53. package/lib/select.js +51 -351
  54. package/lib/styles/common.p.module.css.js +32 -0
  55. package/lib/styles/form-trigger.p.module.css.js +15 -0
  56. package/lib/styles/list-box.p.module.css.js +16 -0
  57. package/lib/types.d.ts +172 -4
  58. package/lib/utils/calculate-max-height-by-items.d.ts +13 -0
  59. package/lib/utils/calculate-max-height-by-items.js +22 -0
  60. package/lib/utils/get-empty-message.d.ts +6 -0
  61. package/lib/utils/get-empty-message.js +32 -0
  62. package/lib/utils/get-option-value.d.ts +2 -0
  63. package/lib/utils/get-option-value.js +11 -0
  64. package/lib/utils/get-real-items-cnt.d.ts +2 -0
  65. package/lib/utils/get-real-items-cnt.js +19 -0
  66. package/lib/utils/get-text-from-nodes.d.ts +2 -0
  67. package/lib/utils/get-text-from-nodes.js +26 -0
  68. package/lib/utils/is-option-a-group.d.ts +2 -0
  69. package/lib/utils/is-option-a-group.js +5 -0
  70. package/lib/utils/item-to-string.d.ts +2 -0
  71. package/lib/utils/item-to-string.js +7 -0
  72. package/lib/utils/merge-props.d.ts +19 -0
  73. package/lib/utils/merge-props.js +104 -0
  74. package/lib/utils/throttle.d.ts +1 -0
  75. package/package.json +8 -8
  76. package/lib/key-codes.d.ts +0 -7
  77. package/lib/key-codes.js +0 -8
  78. package/lib/parts/common-select.p.module.css.js +0 -15
  79. package/lib/parts/form-trigger.p.module.css.js +0 -15
  80. package/lib/parts/multiselect.d.ts +0 -86
  81. package/lib/parts/multiselect.js +0 -455
  82. package/lib/parts/native-select.d.ts +0 -36
  83. package/lib/parts/native-select.js +0 -257
  84. package/lib/parts/native-select.p.module.css.js +0 -9
  85. package/lib/parts/throttle.d.ts +0 -1
  86. package/lib/parts/trigger.d.ts +0 -37
  87. package/lib/parts/trigger.js +0 -255
  88. package/lib/parts/trigger.p.module.css.js +0 -31
  89. package/lib/parts/use-backward-compatible-id.d.ts +0 -4
  90. package/lib/parts/use-backward-compatible-id.js +0 -14
  91. package/lib/parts/use-observable-force-rerender.d.ts +0 -2
  92. package/lib/parts/use-observable-force-rerender.js +0 -16
  93. package/lib/utils.d.ts +0 -22
  94. package/lib/utils.js +0 -201
  95. /package/lib/{parts → utils}/throttle.js +0 -0
@@ -1,15 +1,15 @@
1
1
  var styles = {
2
- "icon": "_icon_e0n0cr_4",
3
- "sizeXS": "_sizeXS_e0n0cr_14",
4
- "sizeS": "_sizeS_e0n0cr_18",
5
- "sizeM": "_sizeM_e0n0cr_22",
6
- "sizeL": "_sizeL_e0n0cr_26",
7
- "light": "_light_e0n0cr_30",
8
- "dark": "_dark_e0n0cr_34",
9
- "allVariants": "_allVariants_e0n0cr_48",
10
- "variant16": "_variant16_e0n0cr_53",
11
- "variant20": "_variant20_e0n0cr_54",
12
- "variant24": "_variant24_e0n0cr_55",
13
- "variant28": "_variant28_e0n0cr_58"
2
+ "icon": "_icon_q2bqnl_4",
3
+ "sizeXS": "_sizeXS_q2bqnl_14",
4
+ "sizeS": "_sizeS_q2bqnl_18",
5
+ "sizeM": "_sizeM_q2bqnl_22",
6
+ "sizeL": "_sizeL_q2bqnl_26",
7
+ "light": "_light_q2bqnl_30",
8
+ "dark": "_dark_q2bqnl_34",
9
+ "allVariants": "_allVariants_q2bqnl_48",
10
+ "variant16": "_variant16_q2bqnl_53",
11
+ "variant20": "_variant20_q2bqnl_54",
12
+ "variant24": "_variant24_q2bqnl_55",
13
+ "variant28": "_variant28_q2bqnl_58"
14
14
  };
15
15
  export { styles as default };
@@ -1,18 +1,20 @@
1
1
  import PropTypes from 'prop-types';
2
+ import type { NoOptionsMessage, NoOptionsMessageConfig } from './types';
3
+ export declare const keyType: PropTypes.Requireable<string | number>;
2
4
  export declare const optionType: PropTypes.Requireable<PropTypes.InferProps<{
3
5
  label: PropTypes.Validator<PropTypes.ReactNodeLike>;
4
- value: PropTypes.Requireable<string>;
6
+ value: PropTypes.Requireable<string | number>;
5
7
  }>>;
6
8
  export declare const optionsGroupType: PropTypes.Requireable<PropTypes.InferProps<{
7
9
  label: PropTypes.Requireable<PropTypes.ReactNodeLike>;
8
10
  options: PropTypes.Requireable<PropTypes.InferProps<{
9
11
  label: PropTypes.Validator<PropTypes.ReactNodeLike>;
10
- value: PropTypes.Requireable<string>;
12
+ value: PropTypes.Requireable<string | number>;
11
13
  }>[]>;
12
14
  }>>;
13
15
  export declare const nativeOptionType: PropTypes.Requireable<PropTypes.InferProps<{
14
16
  label: PropTypes.Validator<string>;
15
- value: PropTypes.Requireable<string>;
17
+ value: PropTypes.Requireable<string | number>;
16
18
  disabled: PropTypes.Requireable<boolean>;
17
19
  }>>;
18
20
  export declare const nativeOptionsGroupType: PropTypes.Requireable<PropTypes.InferProps<{
@@ -20,16 +22,8 @@ export declare const nativeOptionsGroupType: PropTypes.Requireable<PropTypes.Inf
20
22
  disabled: PropTypes.Requireable<boolean>;
21
23
  options: PropTypes.Requireable<PropTypes.InferProps<{
22
24
  label: PropTypes.Validator<PropTypes.ReactNodeLike>;
23
- value: PropTypes.Requireable<string>;
25
+ value: PropTypes.Requireable<string | number>;
24
26
  }>[]>;
25
27
  }>>;
26
- export declare const noOptionsMessageConfigType: PropTypes.Requireable<PropTypes.InferProps<{
27
- noOptions: PropTypes.Validator<string>;
28
- nothingFound: PropTypes.Requireable<string>;
29
- loading: PropTypes.Requireable<string>;
30
- }>>;
31
- export declare const noOptionsMessageType: PropTypes.Requireable<string | PropTypes.InferProps<{
32
- noOptions: PropTypes.Validator<string>;
33
- nothingFound: PropTypes.Requireable<string>;
34
- loading: PropTypes.Requireable<string>;
35
- }>>;
28
+ export declare const noOptionsMessageConfigType: PropTypes.Validator<NoOptionsMessageConfig>;
29
+ export declare const noOptionsMessageType: PropTypes.Validator<NoOptionsMessage>;
@@ -1,7 +1,8 @@
1
1
  import PropTypes from 'prop-types';
2
+ const keyType = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
2
3
  const optionType = PropTypes.shape({
3
4
  label: PropTypes.node.isRequired,
4
- value: PropTypes.string
5
+ value: keyType
5
6
  });
6
7
  const optionsGroupType = PropTypes.shape({
7
8
  label: PropTypes.node,
@@ -9,7 +10,7 @@ const optionsGroupType = PropTypes.shape({
9
10
  });
10
11
  const nativeOptionType = PropTypes.shape({
11
12
  label: PropTypes.string.isRequired,
12
- value: PropTypes.string,
13
+ value: keyType,
13
14
  disabled: PropTypes.bool
14
15
  });
15
16
  const nativeOptionsGroupType = PropTypes.shape({
@@ -23,4 +24,4 @@ const noOptionsMessageConfigType = PropTypes.shape({
23
24
  loading: PropTypes.string
24
25
  });
25
26
  const noOptionsMessageType = PropTypes.oneOfType([PropTypes.string, noOptionsMessageConfigType]);
26
- export { nativeOptionType, nativeOptionsGroupType, noOptionsMessageConfigType, noOptionsMessageType, optionType, optionsGroupType };
27
+ export { keyType, nativeOptionType, nativeOptionsGroupType, noOptionsMessageConfigType, noOptionsMessageType, optionType, optionsGroupType };
@@ -0,0 +1,6 @@
1
+ export declare const NO_OPTIONS_VALUE = "\0__rs_select_no_options__";
2
+ export declare const DEFAULT_NO_OPTIONS_MESSAGES: {
3
+ noOptions: string;
4
+ nothingFound: string;
5
+ loading: string;
6
+ };
@@ -0,0 +1,7 @@
1
+ const NO_OPTIONS_VALUE = '\0__rs_select_no_options__';
2
+ const DEFAULT_NO_OPTIONS_MESSAGES = {
3
+ noOptions: 'No options',
4
+ nothingFound: 'Nothing found',
5
+ loading: 'Loading...'
6
+ };
7
+ export { DEFAULT_NO_OPTIONS_MESSAGES, NO_OPTIONS_VALUE };
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ export declare type UseA11yArgs = {
3
+ prefix?: string;
4
+ baseId?: string;
5
+ description?: React.ReactNode;
6
+ error?: React.ReactNode;
7
+ label?: React.ReactNode;
8
+ fieldRef?: React.RefObject<HTMLElement>;
9
+ isDisabled?: boolean;
10
+ };
11
+ export declare const useA11y: ({ baseId: baseIdFromProps, prefix, description, error, label, fieldRef, isDisabled }: UseA11yArgs) => {
12
+ baseId: string;
13
+ fieldProps: {
14
+ 'aria-invalid': boolean;
15
+ 'aria-describedby': string;
16
+ 'aria-labelledby': string;
17
+ id: string;
18
+ };
19
+ descriptionProps: {
20
+ id: string;
21
+ };
22
+ errorMessageProps: {
23
+ id: string;
24
+ };
25
+ labelProps: {
26
+ id: string;
27
+ htmlFor: string;
28
+ onClick: () => void;
29
+ };
30
+ };
@@ -0,0 +1,56 @@
1
+ import { useSafeId } from './use-safe-id.js'; // eslint-disable-next-line complexity
2
+
3
+ const useA11y = _ref => {
4
+ let {
5
+ baseId: baseIdFromProps,
6
+ prefix = '',
7
+ description,
8
+ error,
9
+ label,
10
+ fieldRef,
11
+ isDisabled = false
12
+ } = _ref;
13
+ const uniqueId = `${prefix ? `${prefix}-` : ''}${useSafeId()}`;
14
+ const baseId = baseIdFromProps ?? uniqueId;
15
+ const fieldId = `${baseId}-field`;
16
+ const descriptionId = description ? `${baseId}-description` : undefined;
17
+ const errorId = error ? `${baseId}-error` : undefined;
18
+ const labelId = label ? `${baseId}-label` : undefined;
19
+ const describedBy = [descriptionId, errorId].filter(Boolean).join(' ') || undefined;
20
+ const fieldProps = {
21
+ 'aria-invalid': Boolean(error),
22
+ 'aria-describedby': describedBy,
23
+ 'aria-labelledby': labelId,
24
+ id: fieldId
25
+ };
26
+ const errorMessageProps = {
27
+ id: errorId
28
+ };
29
+ const descriptionProps = {
30
+ id: descriptionId
31
+ };
32
+ const labelProps = {
33
+ id: labelId,
34
+ htmlFor: fieldId,
35
+ onClick: () => {
36
+ if (isDisabled) {
37
+ return;
38
+ }
39
+
40
+ if (fieldRef?.current) {
41
+ fieldRef.current.focus();
42
+ } else {
43
+ document.getElementById(fieldId)?.focus();
44
+ }
45
+ }
46
+ };
47
+ return {
48
+ baseId,
49
+ fieldProps,
50
+ descriptionProps,
51
+ errorMessageProps,
52
+ labelProps
53
+ };
54
+ };
55
+
56
+ export { useA11y };
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { SelectSize } from '../types';
3
+ export declare type UseActualSizeFromCssParams = {
4
+ sizeFromProps: SelectSize;
5
+ triggerRef: React.RefObject<HTMLElement>;
6
+ };
7
+ export declare const useActualSizeFromCss: ({ sizeFromProps, triggerRef }: UseActualSizeFromCssParams) => {
8
+ observableRef: React.MutableRefObject<undefined>;
9
+ size: "l" | "m" | "s";
10
+ };
@@ -0,0 +1,27 @@
1
+ import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
2
+ import { useRef, useState } from 'react';
3
+ import { useResizeObserver } from '@rescui/use-resize-observer';
4
+
5
+ const useActualSizeFromCss = _ref => {
6
+ let {
7
+ sizeFromProps,
8
+ triggerRef
9
+ } = _ref;
10
+ // We use invisible and "untouchable" dummy element to observe `size` changes from css to fetch the actual size
11
+ const observableRef = useRef();
12
+ const [size, setSize] = useState(sizeFromProps);
13
+ useResizeObserver(observableRef, () => {
14
+ var _context;
15
+
16
+ const triggerFormWrapperStyles = getComputedStyle(triggerRef.current);
17
+ const rawSizeFromCss = triggerFormWrapperStyles.getPropertyValue('--_rs-select-size');
18
+ const sizeFromCss = _includesInstanceProperty(_context = ['s', 'm', 'l']).call(_context, rawSizeFromCss) ? rawSizeFromCss : null;
19
+ setSize(sizeFromCss || sizeFromProps);
20
+ });
21
+ return {
22
+ observableRef,
23
+ size
24
+ };
25
+ };
26
+
27
+ export { useActualSizeFromCss };
@@ -0,0 +1,10 @@
1
+ export declare type UseFocusParams = {
2
+ isDisabled?: boolean;
3
+ };
4
+ export declare const useFocus: ({ isDisabled }: UseFocusParams) => {
5
+ isFocused: boolean;
6
+ focusProps: {
7
+ onFocus: () => void;
8
+ onBlur: () => void;
9
+ };
10
+ };
@@ -0,0 +1,17 @@
1
+ import { useState } from 'react';
2
+
3
+ const useFocus = _ref => {
4
+ let {
5
+ isDisabled
6
+ } = _ref;
7
+ const [isFocused, setIsFocused] = useState(false);
8
+ return {
9
+ isFocused,
10
+ focusProps: {
11
+ onFocus: () => setIsFocused(!isDisabled),
12
+ onBlur: () => setIsFocused(false)
13
+ }
14
+ };
15
+ };
16
+
17
+ export { useFocus };
@@ -0,0 +1,10 @@
1
+ export declare type UseHoverParams = {
2
+ isDisabled?: boolean;
3
+ };
4
+ export declare const useHover: ({ isDisabled }: UseHoverParams) => {
5
+ isHovered: boolean;
6
+ hoverProps: {
7
+ onMouseEnter: () => void;
8
+ onMouseLeave: () => void;
9
+ };
10
+ };
@@ -0,0 +1,17 @@
1
+ import { useState } from 'react';
2
+
3
+ const useHover = _ref => {
4
+ let {
5
+ isDisabled
6
+ } = _ref;
7
+ const [isHovered, setIsHovered] = useState(false);
8
+ return {
9
+ isHovered,
10
+ hoverProps: {
11
+ onMouseEnter: () => setIsHovered(!isDisabled),
12
+ onMouseLeave: () => setIsHovered(false)
13
+ }
14
+ };
15
+ };
16
+
17
+ export { useHover };
@@ -0,0 +1,9 @@
1
+ export declare const useLabelFocus: () => {
2
+ isFocusedByLabel: boolean;
3
+ triggerFocusProps: {
4
+ onBlur: () => void;
5
+ };
6
+ labelClickProps: {
7
+ onClick: () => void;
8
+ };
9
+ };
@@ -0,0 +1,22 @@
1
+ import { useState } from 'react';
2
+
3
+ const useLabelFocus = () => {
4
+ const [isFocusedByLabel, setIsFocusedByLabel] = useState(false);
5
+ const triggerFocusProps = {
6
+ onBlur: () => {
7
+ setIsFocusedByLabel(false);
8
+ }
9
+ };
10
+ const labelClickProps = {
11
+ onClick: () => {
12
+ setIsFocusedByLabel(true);
13
+ }
14
+ };
15
+ return {
16
+ isFocusedByLabel,
17
+ triggerFocusProps,
18
+ labelClickProps
19
+ };
20
+ };
21
+
22
+ export { useLabelFocus };
@@ -0,0 +1,11 @@
1
+ import type { SelectOption } from '../types';
2
+ export declare type UseMultiHandlersArgs = {
3
+ selectedItems: SelectOption[];
4
+ onChange: (value: SelectOption[]) => void;
5
+ };
6
+ export declare const useMultiHandlers: ({ selectedItems, onChange }: UseMultiHandlersArgs) => {
7
+ selectedMap: Map<import("../types").Key, SelectOption>;
8
+ addItem: (item: SelectOption) => void;
9
+ removeItem: (item: SelectOption) => void;
10
+ removeAllItems: () => void;
11
+ };
@@ -0,0 +1,44 @@
1
+ import { useRef, useMemo, useCallback } from 'react';
2
+ import { getOptionValue } from '../utils/get-option-value.js';
3
+
4
+ const useMultiHandlers = _ref => {
5
+ let {
6
+ selectedItems,
7
+ onChange
8
+ } = _ref;
9
+ const onChangeRef = useRef(null);
10
+ onChangeRef.current = onChange;
11
+ const selectedMap = useMemo(() => new Map(selectedItems.map(item => [getOptionValue(item), item])), [selectedItems]);
12
+ const addItem = useCallback(item => {
13
+ if (selectedMap.has(getOptionValue(item))) {
14
+ return;
15
+ }
16
+
17
+ const newValues = [...selectedMap.values(), item];
18
+ onChangeRef.current?.(newValues);
19
+ }, [selectedMap]);
20
+ const removeItem = useCallback(item => {
21
+ const key = getOptionValue(item);
22
+ const newValues = [...selectedMap.entries()].filter(_ref2 => {
23
+ let [k] = _ref2;
24
+ return k !== key;
25
+ }).map(_ref3 => {
26
+ let [, v] = _ref3;
27
+ return v;
28
+ });
29
+ onChangeRef.current?.(newValues);
30
+ }, [selectedMap]);
31
+
32
+ const removeAllItems = () => {
33
+ onChangeRef.current?.([]);
34
+ };
35
+
36
+ return {
37
+ selectedMap,
38
+ addItem,
39
+ removeItem,
40
+ removeAllItems
41
+ };
42
+ };
43
+
44
+ export { useMultiHandlers };
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ import type { SelectOptionOrGroup, SelectOption, ListBoxItem } from '../types';
3
+ /**
4
+ * Convert an array of options with possible groups to the flat array of options, stripping them of the groups.
5
+ * Also creating a list for ListBox component with indexes and keys.
6
+ * Supports filtering by returning the setFilterString function.
7
+ * @param options
8
+ */
9
+ export declare const useOptions: (options: SelectOptionOrGroup[]) => {
10
+ setFilterString: import("react").Dispatch<import("react").SetStateAction<string>>;
11
+ filterString: string;
12
+ flattenedOptions: SelectOption[];
13
+ listBoxItems: ListBoxItem[];
14
+ };
@@ -0,0 +1,90 @@
1
+ import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
2
+ import { useState, useMemo } from 'react';
3
+ import { isOptionAGroup } from '../utils/is-option-a-group.js';
4
+ import { getTextFromNodes } from '../utils/get-text-from-nodes.js';
5
+ import { getOptionValue } from '../utils/get-option-value.js';
6
+
7
+ const createFilter = substring => {
8
+ if (substring.length === 0) {
9
+ return () => true;
10
+ }
11
+
12
+ const lowerSubstring = substring.toLowerCase();
13
+ return string => {
14
+ var _context;
15
+
16
+ return _includesInstanceProperty(_context = string.toLowerCase()).call(_context, lowerSubstring);
17
+ };
18
+ };
19
+ /**
20
+ * Convert an array of options with possible groups to the flat array of options, stripping them of the groups.
21
+ * Also creating a list for ListBox component with indexes and keys.
22
+ * Supports filtering by returning the setFilterString function.
23
+ * @param options
24
+ */
25
+
26
+
27
+ const useOptions = options => {
28
+ const [filterString, setFilterString] = useState('');
29
+ const filterFn = useMemo(() => createFilter(filterString), [filterString]);
30
+ const processedOptions = useMemo(() => {
31
+ const flattenedOptions = [];
32
+ const listBoxItems = [];
33
+ let index = 0;
34
+
35
+ const createOptionItem = option => {
36
+ return { ...option,
37
+ index: index++,
38
+ type: 'option',
39
+ key: getOptionValue(option)
40
+ };
41
+ };
42
+
43
+ options.forEach((optionOrGroup, arrayIndex) => {
44
+ if (isOptionAGroup(optionOrGroup)) {
45
+ const group = optionOrGroup;
46
+
47
+ if (!group.options || group.options.length === 0) {
48
+ return;
49
+ } // Render as Group (with or without label)
50
+
51
+
52
+ const groupLabelText = group.label ? getTextFromNodes(group.label) : ''; // Use a special prefix that's unlikely to collide with user values
53
+
54
+ const groupKey = `\0__rs_select_group_${arrayIndex}_${groupLabelText}`;
55
+ const listBoxGroupItem = { ...group,
56
+ type: 'group',
57
+ options: [],
58
+ key: groupKey
59
+ };
60
+ group.options.forEach(option => {
61
+ if (filterFn(getTextFromNodes(option.label))) {
62
+ flattenedOptions.push(option);
63
+ listBoxGroupItem.options.push(createOptionItem(option));
64
+ }
65
+ });
66
+
67
+ if (listBoxGroupItem.options.length > 0) {
68
+ listBoxItems.push(listBoxGroupItem);
69
+ }
70
+
71
+ return;
72
+ }
73
+
74
+ if (filterFn(getTextFromNodes(optionOrGroup.label))) {
75
+ flattenedOptions.push(optionOrGroup);
76
+ listBoxItems.push(createOptionItem(optionOrGroup));
77
+ }
78
+ });
79
+ return {
80
+ flattenedOptions,
81
+ listBoxItems
82
+ };
83
+ }, [options, filterFn]);
84
+ return { ...processedOptions,
85
+ setFilterString,
86
+ filterString
87
+ };
88
+ };
89
+
90
+ export { useOptions };
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export declare type UsePrimaryContrastCssVarTransferParams = {
3
+ triggerRef: React.RefObject<HTMLElement>;
4
+ isOpen: boolean;
5
+ };
6
+ /**
7
+ * Transfer primary contrast css var to the dropdown, but only when the dropdown opens
8
+ */
9
+ export declare const usePrimaryContrastCssVarTransfer: ({ triggerRef, isOpen }: UsePrimaryContrastCssVarTransferParams) => {
10
+ isPrimaryContrast: boolean;
11
+ };
@@ -0,0 +1,29 @@
1
+ import { useRef } from 'react';
2
+ /**
3
+ * Transfer primary contrast css var to the dropdown, but only when the dropdown opens
4
+ */
5
+
6
+ const usePrimaryContrastCssVarTransfer = _ref => {
7
+ let {
8
+ triggerRef,
9
+ isOpen
10
+ } = _ref;
11
+ const prevIsOpenRef = useRef(false);
12
+ const isPrimaryContrastRef = useRef(false);
13
+
14
+ if (prevIsOpenRef.current !== isOpen && isOpen && triggerRef.current && typeof window !== 'undefined') {
15
+ const isPrimaryContrastFromCss = getComputedStyle(triggerRef.current)?.getPropertyValue('--rs-select-contrast-primary');
16
+ isPrimaryContrastRef.current = isPrimaryContrastFromCss.toString() === '1';
17
+ prevIsOpenRef.current = true;
18
+ }
19
+
20
+ if (!isOpen) {
21
+ prevIsOpenRef.current = false;
22
+ }
23
+
24
+ return {
25
+ isPrimaryContrast: isPrimaryContrastRef.current
26
+ };
27
+ };
28
+
29
+ export { usePrimaryContrastCssVarTransfer };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare const useFallbackId: {
3
+ (): string;
4
+ counter: number;
5
+ };
6
+ export declare const useSafeId: typeof React.useId;
@@ -0,0 +1,15 @@
1
+ import React, { useRef } from 'react';
2
+
3
+ const useFallbackId = () => {
4
+ const id = useRef(null);
5
+
6
+ if (id.current === null) {
7
+ id.current = useFallbackId.counter++;
8
+ }
9
+
10
+ return id.current.toString();
11
+ };
12
+
13
+ useFallbackId.counter = 0;
14
+ const useSafeId = React.useId ?? useFallbackId;
15
+ export { useFallbackId, useSafeId };