@pushwoosh/dumb-components 1.1.141 → 1.1.142
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/Combobox/Combobox.js +19 -1
- package/Combobox/types.d.ts +2 -0
- package/ComboboxMulti/ComboboxMulti.d.ts +1 -1
- package/ComboboxMulti/ComboboxMulti.js +10 -1
- package/ComboboxMulti/types.d.ts +2 -0
- package/package.json +1 -1
- package/shared/dropdownField/FieldShell.js +11 -0
- package/shared/dropdownField/index.d.ts +1 -0
- package/shared/dropdownField/index.js +1 -0
- package/shared/dropdownField/useDropdownPosition.d.ts +1 -0
- package/shared/dropdownField/useDropdownPosition.js +1 -0
- package/shared/dropdownField/useFieldOpenEffects.d.ts +10 -0
- package/shared/dropdownField/useFieldOpenEffects.js +25 -0
package/Combobox/Combobox.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useId, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { DEFAULT_DEBOUNCE_MS, FieldInput, FieldShell, defaultGetKey, useActiveIndex, useDropdownItems, useListNavigation, useShellMouseDown } from '../shared/dropdownField';
|
|
3
|
+
import { DEFAULT_DEBOUNCE_MS, FieldInput, FieldShell, defaultGetKey, useActiveIndex, useDropdownItems, useFieldOpenEffects, useListNavigation, useShellMouseDown } from '../shared/dropdownField';
|
|
4
4
|
function FreeCombobox({
|
|
5
5
|
items,
|
|
6
6
|
loadItems,
|
|
7
7
|
debounceMs = DEFAULT_DEBOUNCE_MS,
|
|
8
8
|
value,
|
|
9
9
|
onChange,
|
|
10
|
+
onClose,
|
|
11
|
+
autoFocus,
|
|
10
12
|
getLabel: getLabelProp,
|
|
11
13
|
filter,
|
|
12
14
|
renderItem,
|
|
@@ -58,6 +60,13 @@ function FreeCombobox({
|
|
|
58
60
|
onEscape: close
|
|
59
61
|
});
|
|
60
62
|
const onShellMouseDown = useShellMouseDown(inputRef, isOpen, open);
|
|
63
|
+
useFieldOpenEffects({
|
|
64
|
+
isOpen,
|
|
65
|
+
open,
|
|
66
|
+
onClose,
|
|
67
|
+
autoFocus,
|
|
68
|
+
inputRef
|
|
69
|
+
});
|
|
61
70
|
const dropdownItems = useMemo(() => filteredItems.map((item, idx) => {
|
|
62
71
|
const selected = getLabel(item) === value;
|
|
63
72
|
const state = {
|
|
@@ -122,6 +131,8 @@ function SelectCombobox({
|
|
|
122
131
|
debounceMs = DEFAULT_DEBOUNCE_MS,
|
|
123
132
|
value,
|
|
124
133
|
onChange,
|
|
134
|
+
onClose,
|
|
135
|
+
autoFocus,
|
|
125
136
|
getLabel,
|
|
126
137
|
getKey: getKeyProp,
|
|
127
138
|
filter,
|
|
@@ -190,6 +201,13 @@ function SelectCombobox({
|
|
|
190
201
|
onEscape: close
|
|
191
202
|
});
|
|
192
203
|
const onShellMouseDown = useShellMouseDown(inputRef, isOpen, open);
|
|
204
|
+
useFieldOpenEffects({
|
|
205
|
+
isOpen,
|
|
206
|
+
open,
|
|
207
|
+
onClose,
|
|
208
|
+
autoFocus,
|
|
209
|
+
inputRef
|
|
210
|
+
});
|
|
193
211
|
const dropdownItems = useMemo(() => filteredItems.map((item, idx) => {
|
|
194
212
|
const key = getKey(item);
|
|
195
213
|
const selected = key === selectedKey;
|
package/Combobox/types.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ type CommonProps<T> = {
|
|
|
13
13
|
filter?: (item: T, query: string) => boolean;
|
|
14
14
|
renderItem?: (item: T, state: ItemState) => ReactNode;
|
|
15
15
|
renderEmpty?: (query: string) => ReactNode;
|
|
16
|
+
onClose?: () => void;
|
|
17
|
+
autoFocus?: boolean;
|
|
16
18
|
placeholder?: string;
|
|
17
19
|
disabled?: boolean;
|
|
18
20
|
loading?: boolean;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
2
|
import { type ComboboxMultiProps } from './types';
|
|
3
|
-
export declare function ComboboxMulti<T>({ items, loadItems, debounceMs, value, onChange, getLabel, getKey: getKeyProp, filter, renderItem, renderEmpty, creatable, onCreate, canCreate, renderCreateLabel, maxValues, placeholder, disabled, loading, clearable, autosize, $isErrored, width, minWidth, }: ComboboxMultiProps<T>): ReactElement;
|
|
3
|
+
export declare function ComboboxMulti<T>({ items, loadItems, debounceMs, value, onChange, onClose, autoFocus, getLabel, getKey: getKeyProp, filter, renderItem, renderEmpty, creatable, onCreate, canCreate, renderCreateLabel, maxValues, placeholder, disabled, loading, clearable, autosize, $isErrored, width, minWidth, }: ComboboxMultiProps<T>): ReactElement;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useId, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { Chip } from '../Chip';
|
|
4
|
-
import { DEFAULT_DEBOUNCE_MS, FieldInput, FieldShell, defaultGetKey, useActiveIndex, useDropdownItems, useListNavigation, useShellMouseDown } from '../shared/dropdownField';
|
|
4
|
+
import { DEFAULT_DEBOUNCE_MS, FieldInput, FieldShell, defaultGetKey, useActiveIndex, useDropdownItems, useFieldOpenEffects, useListNavigation, useShellMouseDown } from '../shared/dropdownField';
|
|
5
5
|
function defaultCanCreate(query, items, getLabel) {
|
|
6
6
|
const trimmed = query.trim();
|
|
7
7
|
if (!trimmed) return false;
|
|
@@ -14,6 +14,8 @@ export function ComboboxMulti({
|
|
|
14
14
|
debounceMs = DEFAULT_DEBOUNCE_MS,
|
|
15
15
|
value,
|
|
16
16
|
onChange,
|
|
17
|
+
onClose,
|
|
18
|
+
autoFocus,
|
|
17
19
|
getLabel,
|
|
18
20
|
getKey: getKeyProp,
|
|
19
21
|
filter,
|
|
@@ -107,6 +109,13 @@ export function ComboboxMulti({
|
|
|
107
109
|
onBackspaceEmpty: () => onChange(value.slice(0, -1))
|
|
108
110
|
});
|
|
109
111
|
const onShellMouseDown = useShellMouseDown(inputRef, isOpen, open);
|
|
112
|
+
useFieldOpenEffects({
|
|
113
|
+
isOpen,
|
|
114
|
+
open,
|
|
115
|
+
onClose,
|
|
116
|
+
autoFocus,
|
|
117
|
+
inputRef
|
|
118
|
+
});
|
|
110
119
|
const toggleOpen = useCallback(() => {
|
|
111
120
|
if (isOpen) {
|
|
112
121
|
var _inputRef$current2;
|
package/ComboboxMulti/types.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ type CreatableProp<T> = [T] extends [string] ? {
|
|
|
13
13
|
export type ComboboxMultiProps<T> = ItemsSource<T> & GetKeyProp<T> & CreatableProp<T> & {
|
|
14
14
|
value: T[];
|
|
15
15
|
onChange: (value: T[]) => void;
|
|
16
|
+
onClose?: () => void;
|
|
17
|
+
autoFocus?: boolean;
|
|
16
18
|
getLabel: (item: T) => string;
|
|
17
19
|
filter?: (item: T, query: string) => boolean;
|
|
18
20
|
renderItem?: (item: T, state: ItemState) => ReactNode;
|
package/package.json
CHANGED
|
@@ -33,6 +33,7 @@ export function FieldShell({
|
|
|
33
33
|
const {
|
|
34
34
|
setReference,
|
|
35
35
|
setFloating,
|
|
36
|
+
floatingRef,
|
|
36
37
|
floatingStyles
|
|
37
38
|
} = useDropdownPosition({
|
|
38
39
|
isOpen: dropdownOpen,
|
|
@@ -44,6 +45,15 @@ export function FieldShell({
|
|
|
44
45
|
isOpen: !!dropdownOpen,
|
|
45
46
|
onClose
|
|
46
47
|
});
|
|
48
|
+
const onShellBlur = event => {
|
|
49
|
+
var _floatingRef$current;
|
|
50
|
+
if (!isOpen) return;
|
|
51
|
+
const next = event.relatedTarget;
|
|
52
|
+
if (!next) return;
|
|
53
|
+
if (event.currentTarget.contains(next)) return;
|
|
54
|
+
if ((_floatingRef$current = floatingRef.current) !== null && _floatingRef$current !== void 0 && _floatingRef$current.contains(next)) return;
|
|
55
|
+
onClose === null || onClose === void 0 || onClose();
|
|
56
|
+
};
|
|
47
57
|
return _jsxs(_Fragment, {
|
|
48
58
|
children: [_jsxs(Shell, {
|
|
49
59
|
ref: setReference,
|
|
@@ -56,6 +66,7 @@ export function FieldShell({
|
|
|
56
66
|
"$autosize": autosize,
|
|
57
67
|
"$tightLeft": tightLeft,
|
|
58
68
|
onMouseDown: onShellMouseDown,
|
|
69
|
+
onBlur: onShellBlur,
|
|
59
70
|
children: [_jsx(ShellInner, {
|
|
60
71
|
children: children
|
|
61
72
|
}), _jsxs(Indicators, {
|
|
@@ -6,6 +6,7 @@ export { useDebouncedValue } from './useDebouncedValue';
|
|
|
6
6
|
export { useAsyncItems } from './useAsyncItems';
|
|
7
7
|
export { useDropdownItems } from './useDropdownItems';
|
|
8
8
|
export { useActiveIndex } from './useActiveIndex';
|
|
9
|
+
export { useFieldOpenEffects } from './useFieldOpenEffects';
|
|
9
10
|
export { useListNavigation } from './useListNavigation';
|
|
10
11
|
export { defaultGetKey, defaultLabelFilter, useShellMouseDown } from './shared';
|
|
11
12
|
export { DEFAULT_DEBOUNCE_MS } from './constants';
|
|
@@ -6,6 +6,7 @@ export { useDebouncedValue } from './useDebouncedValue';
|
|
|
6
6
|
export { useAsyncItems } from './useAsyncItems';
|
|
7
7
|
export { useDropdownItems } from './useDropdownItems';
|
|
8
8
|
export { useActiveIndex } from './useActiveIndex';
|
|
9
|
+
export { useFieldOpenEffects } from './useFieldOpenEffects';
|
|
9
10
|
export { useListNavigation } from './useListNavigation';
|
|
10
11
|
export { defaultGetKey, defaultLabelFilter, useShellMouseDown } from './shared';
|
|
11
12
|
export { DEFAULT_DEBOUNCE_MS } from './constants';
|
|
@@ -5,6 +5,7 @@ type Args = {
|
|
|
5
5
|
export declare function useDropdownPosition({ isOpen, onClickOutside }: Args): {
|
|
6
6
|
setReference: (node: import("@floating-ui/react-dom").ReferenceType | null) => void;
|
|
7
7
|
setFloating: (node: HTMLElement | null) => void;
|
|
8
|
+
floatingRef: import("react").MutableRefObject<HTMLElement | null>;
|
|
8
9
|
floatingStyles: import("react").CSSProperties;
|
|
9
10
|
};
|
|
10
11
|
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
type Args = {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
open: () => void;
|
|
5
|
+
onClose?: () => void;
|
|
6
|
+
autoFocus?: boolean;
|
|
7
|
+
inputRef: RefObject<HTMLInputElement>;
|
|
8
|
+
};
|
|
9
|
+
export declare function useFieldOpenEffects({ isOpen, open, onClose, autoFocus, inputRef, }: Args): void;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
export function useFieldOpenEffects({
|
|
3
|
+
isOpen,
|
|
4
|
+
open,
|
|
5
|
+
onClose,
|
|
6
|
+
autoFocus,
|
|
7
|
+
inputRef
|
|
8
|
+
}) {
|
|
9
|
+
const onCloseRef = useRef(onClose);
|
|
10
|
+
onCloseRef.current = onClose;
|
|
11
|
+
const wasOpenRef = useRef(isOpen);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
var _onCloseRef$current;
|
|
14
|
+
if (wasOpenRef.current && !isOpen) (_onCloseRef$current = onCloseRef.current) === null || _onCloseRef$current === void 0 || _onCloseRef$current.call(onCloseRef);
|
|
15
|
+
wasOpenRef.current = isOpen;
|
|
16
|
+
}, [isOpen]);
|
|
17
|
+
const didAutoFocusRef = useRef(false);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
var _inputRef$current;
|
|
20
|
+
if (!autoFocus || didAutoFocusRef.current) return;
|
|
21
|
+
didAutoFocusRef.current = true;
|
|
22
|
+
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
|
|
23
|
+
open();
|
|
24
|
+
}, [autoFocus, open, inputRef]);
|
|
25
|
+
}
|