@rc-component/select 1.0.4 → 1.0.6

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/es/OptionList.js CHANGED
@@ -127,19 +127,20 @@ const OptionList = (_, ref) => {
127
127
  * `setActive` function will call root accessibility state update which makes re-render.
128
128
  * So we need to delay to let Input component trigger onChange first.
129
129
  */
130
- const timeoutId = setTimeout(() => {
131
- if (!multiple && open && rawValues.size === 1) {
132
- const value = Array.from(rawValues)[0];
133
- // Scroll to the option closest to the searchValue if searching.
134
- const index = memoFlattenOptions.findIndex(({
135
- data
136
- }) => searchValue ? String(data.value).startsWith(searchValue) : data.value === value);
137
- if (index !== -1) {
138
- setActive(index);
130
+ let timeoutId;
131
+ if (!multiple && open && rawValues.size === 1) {
132
+ const value = Array.from(rawValues)[0];
133
+ // Scroll to the option closest to the searchValue if searching.
134
+ const index = memoFlattenOptions.findIndex(({
135
+ data
136
+ }) => searchValue ? String(data.value).startsWith(searchValue) : data.value === value);
137
+ if (index !== -1) {
138
+ setActive(index);
139
+ timeoutId = setTimeout(() => {
139
140
  scrollIntoView(index);
140
- }
141
+ });
141
142
  }
142
- });
143
+ }
143
144
 
144
145
  // Force trigger scrollbar visible when open
145
146
  if (open) {
package/es/Select.d.ts CHANGED
@@ -77,6 +77,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
77
77
  autoClearSearchValue?: boolean;
78
78
  onSelect?: SelectHandler<ArrayElementType<ValueType>, OptionType>;
79
79
  onDeselect?: SelectHandler<ArrayElementType<ValueType>, OptionType>;
80
+ onActive?: (value: ValueType) => void;
80
81
  /**
81
82
  * In Select, `false` means do nothing.
82
83
  * In TreeSelect, `false` will highlight match item.
@@ -109,9 +110,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
109
110
  classNames?: Partial<Record<SemanticName, string>>;
110
111
  styles?: Partial<Record<SemanticName, React.CSSProperties>>;
111
112
  }
112
- declare const TypedSelect: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: SelectProps<ValueType, OptionType> & {
113
- children?: React.ReactNode;
114
- } & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
113
+ declare const TypedSelect: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
115
114
  Option: typeof Option;
116
115
  OptGroup: typeof OptGroup;
117
116
  };
package/es/Select.js CHANGED
@@ -40,7 +40,7 @@ import OptionList from "./OptionList";
40
40
  import SelectContext from "./SelectContext";
41
41
  import useCache from "./hooks/useCache";
42
42
  import useFilterOptions from "./hooks/useFilterOptions";
43
- import useId from "./hooks/useId";
43
+ import useId from "@rc-component/util/es/hooks/useId";
44
44
  import useOptions from "./hooks/useOptions";
45
45
  import useRefFunc from "./hooks/useRefFunc";
46
46
  import { hasValue, isComboNoValue, toArray } from "./utils/commonUtil";
@@ -64,6 +64,7 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
64
64
  // Select
65
65
  onSelect,
66
66
  onDeselect,
67
+ onActive,
67
68
  popupMatchSelectWidth = true,
68
69
  // Options
69
70
  filterOption,
@@ -305,6 +306,7 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
305
306
  const [activeValue, setActiveValue] = React.useState(null);
306
307
  const [accessibilityIndex, setAccessibilityIndex] = React.useState(0);
307
308
  const mergedDefaultActiveFirstOption = defaultActiveFirstOption !== undefined ? defaultActiveFirstOption : mode !== 'combobox';
309
+ const activeEventRef = React.useRef();
308
310
  const onActiveValue = React.useCallback((active, index, {
309
311
  source = 'keyboard'
310
312
  } = {}) => {
@@ -312,7 +314,16 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
312
314
  if (backfill && mode === 'combobox' && active !== null && source === 'keyboard') {
313
315
  setActiveValue(String(active));
314
316
  }
315
- }, [backfill, mode]);
317
+
318
+ // Active will call multiple times.
319
+ // We only need trigger the last one.
320
+ const promise = Promise.resolve().then(() => {
321
+ if (activeEventRef.current === promise) {
322
+ onActive?.(active);
323
+ }
324
+ });
325
+ activeEventRef.current = promise;
326
+ }, [backfill, mode, onActive]);
316
327
 
317
328
  // ========================= OptionList =========================
318
329
  const triggerSelect = (val, selected, type) => {
package/lib/OptionList.js CHANGED
@@ -135,19 +135,20 @@ const OptionList = (_, ref) => {
135
135
  * `setActive` function will call root accessibility state update which makes re-render.
136
136
  * So we need to delay to let Input component trigger onChange first.
137
137
  */
138
- const timeoutId = setTimeout(() => {
139
- if (!multiple && open && rawValues.size === 1) {
140
- const value = Array.from(rawValues)[0];
141
- // Scroll to the option closest to the searchValue if searching.
142
- const index = memoFlattenOptions.findIndex(({
143
- data
144
- }) => searchValue ? String(data.value).startsWith(searchValue) : data.value === value);
145
- if (index !== -1) {
146
- setActive(index);
138
+ let timeoutId;
139
+ if (!multiple && open && rawValues.size === 1) {
140
+ const value = Array.from(rawValues)[0];
141
+ // Scroll to the option closest to the searchValue if searching.
142
+ const index = memoFlattenOptions.findIndex(({
143
+ data
144
+ }) => searchValue ? String(data.value).startsWith(searchValue) : data.value === value);
145
+ if (index !== -1) {
146
+ setActive(index);
147
+ timeoutId = setTimeout(() => {
147
148
  scrollIntoView(index);
148
- }
149
+ });
149
150
  }
150
- });
151
+ }
151
152
 
152
153
  // Force trigger scrollbar visible when open
153
154
  if (open) {
package/lib/Select.d.ts CHANGED
@@ -77,6 +77,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
77
77
  autoClearSearchValue?: boolean;
78
78
  onSelect?: SelectHandler<ArrayElementType<ValueType>, OptionType>;
79
79
  onDeselect?: SelectHandler<ArrayElementType<ValueType>, OptionType>;
80
+ onActive?: (value: ValueType) => void;
80
81
  /**
81
82
  * In Select, `false` means do nothing.
82
83
  * In TreeSelect, `false` will highlight match item.
@@ -109,9 +110,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
109
110
  classNames?: Partial<Record<SemanticName, string>>;
110
111
  styles?: Partial<Record<SemanticName, React.CSSProperties>>;
111
112
  }
112
- declare const TypedSelect: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: SelectProps<ValueType, OptionType> & {
113
- children?: React.ReactNode;
114
- } & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
113
+ declare const TypedSelect: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
115
114
  Option: typeof Option;
116
115
  OptGroup: typeof OptGroup;
117
116
  };
package/lib/Select.js CHANGED
@@ -14,7 +14,7 @@ var _OptionList = _interopRequireDefault(require("./OptionList"));
14
14
  var _SelectContext = _interopRequireDefault(require("./SelectContext"));
15
15
  var _useCache = _interopRequireDefault(require("./hooks/useCache"));
16
16
  var _useFilterOptions = _interopRequireDefault(require("./hooks/useFilterOptions"));
17
- var _useId = _interopRequireDefault(require("./hooks/useId"));
17
+ var _useId = _interopRequireDefault(require("@rc-component/util/lib/hooks/useId"));
18
18
  var _useOptions = _interopRequireDefault(require("./hooks/useOptions"));
19
19
  var _useRefFunc = _interopRequireDefault(require("./hooks/useRefFunc"));
20
20
  var _commonUtil = require("./utils/commonUtil");
@@ -71,6 +71,7 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
71
71
  // Select
72
72
  onSelect,
73
73
  onDeselect,
74
+ onActive,
74
75
  popupMatchSelectWidth = true,
75
76
  // Options
76
77
  filterOption,
@@ -312,6 +313,7 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
312
313
  const [activeValue, setActiveValue] = React.useState(null);
313
314
  const [accessibilityIndex, setAccessibilityIndex] = React.useState(0);
314
315
  const mergedDefaultActiveFirstOption = defaultActiveFirstOption !== undefined ? defaultActiveFirstOption : mode !== 'combobox';
316
+ const activeEventRef = React.useRef();
315
317
  const onActiveValue = React.useCallback((active, index, {
316
318
  source = 'keyboard'
317
319
  } = {}) => {
@@ -319,7 +321,16 @@ const Select = /*#__PURE__*/React.forwardRef((props, ref) => {
319
321
  if (backfill && mode === 'combobox' && active !== null && source === 'keyboard') {
320
322
  setActiveValue(String(active));
321
323
  }
322
- }, [backfill, mode]);
324
+
325
+ // Active will call multiple times.
326
+ // We only need trigger the last one.
327
+ const promise = Promise.resolve().then(() => {
328
+ if (activeEventRef.current === promise) {
329
+ onActive?.(active);
330
+ }
331
+ });
332
+ activeEventRef.current = promise;
333
+ }, [backfill, mode, onActive]);
323
334
 
324
335
  // ========================= OptionList =========================
325
336
  const triggerSelect = (val, selected, type) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rc-component/select",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "React Select",
5
5
  "engines": {
6
6
  "node": ">=8.x"
@@ -1,5 +0,0 @@
1
- /** Is client side and not jsdom */
2
- export declare const isBrowserClient: boolean;
3
- /** Get unique id for accessibility usage */
4
- export declare function getUUID(): number | string;
5
- export default function useId(id?: string): string;
package/es/hooks/useId.js DELETED
@@ -1,29 +0,0 @@
1
- import * as React from 'react';
2
- import canUseDom from "@rc-component/util/es/Dom/canUseDom";
3
- let uuid = 0;
4
-
5
- /** Is client side and not jsdom */
6
- export const isBrowserClient = process.env.NODE_ENV !== 'test' && canUseDom();
7
-
8
- /** Get unique id for accessibility usage */
9
- export function getUUID() {
10
- let retId;
11
-
12
- // Test never reach
13
- /* istanbul ignore if */
14
- if (isBrowserClient) {
15
- retId = uuid;
16
- uuid += 1;
17
- } else {
18
- retId = 'TEST_OR_SSR';
19
- }
20
- return retId;
21
- }
22
- export default function useId(id) {
23
- // Inner id for accessibility usage. Only work in client side
24
- const [innerId, setInnerId] = React.useState();
25
- React.useEffect(() => {
26
- setInnerId(`rc_select_${getUUID()}`);
27
- }, []);
28
- return id || innerId;
29
- }
@@ -1,5 +0,0 @@
1
- /** Is client side and not jsdom */
2
- export declare const isBrowserClient: boolean;
3
- /** Get unique id for accessibility usage */
4
- export declare function getUUID(): number | string;
5
- export default function useId(id?: string): string;
@@ -1,40 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = useId;
7
- exports.getUUID = getUUID;
8
- exports.isBrowserClient = void 0;
9
- var React = _interopRequireWildcard(require("react"));
10
- var _canUseDom = _interopRequireDefault(require("@rc-component/util/lib/Dom/canUseDom"));
11
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
13
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
14
- let uuid = 0;
15
-
16
- /** Is client side and not jsdom */
17
- const isBrowserClient = exports.isBrowserClient = process.env.NODE_ENV !== 'test' && (0, _canUseDom.default)();
18
-
19
- /** Get unique id for accessibility usage */
20
- function getUUID() {
21
- let retId;
22
-
23
- // Test never reach
24
- /* istanbul ignore if */
25
- if (isBrowserClient) {
26
- retId = uuid;
27
- uuid += 1;
28
- } else {
29
- retId = 'TEST_OR_SSR';
30
- }
31
- return retId;
32
- }
33
- function useId(id) {
34
- // Inner id for accessibility usage. Only work in client side
35
- const [innerId, setInnerId] = React.useState();
36
- React.useEffect(() => {
37
- setInnerId(`rc_select_${getUUID()}`);
38
- }, []);
39
- return id || innerId;
40
- }