@deephaven/components 1.20.0 → 1.21.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.
- package/dist/spectrum/comboBox/ComboBox.d.ts +1 -1
- package/dist/spectrum/index.d.ts +1 -0
- package/dist/spectrum/index.d.ts.map +1 -1
- package/dist/spectrum/index.js +1 -0
- package/dist/spectrum/index.js.map +1 -1
- package/dist/spectrum/listView/ListView.d.ts +1 -1
- package/dist/spectrum/listView/ListView.d.ts.map +1 -1
- package/dist/spectrum/listView/ListView.js.map +1 -1
- package/dist/spectrum/multiSelect/MultiSelect.css +326 -0
- package/dist/spectrum/multiSelect/MultiSelect.css.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelect.d.ts +7 -0
- package/dist/spectrum/multiSelect/MultiSelect.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelect.js +445 -0
- package/dist/spectrum/multiSelect/MultiSelect.js.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectListBox.d.ts +29 -0
- package/dist/spectrum/multiSelect/MultiSelectListBox.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectListBox.js +41 -0
- package/dist/spectrum/multiSelect/MultiSelectListBox.js.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectNormalized.d.ts +8 -0
- package/dist/spectrum/multiSelect/MultiSelectNormalized.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectNormalized.js +37 -0
- package/dist/spectrum/multiSelect/MultiSelectNormalized.js.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectProps.d.ts +121 -0
- package/dist/spectrum/multiSelect/MultiSelectProps.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectProps.js +2 -0
- package/dist/spectrum/multiSelect/MultiSelectProps.js.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectTag.d.ts +14 -0
- package/dist/spectrum/multiSelect/MultiSelectTag.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/MultiSelectTag.js +36 -0
- package/dist/spectrum/multiSelect/MultiSelectTag.js.map +1 -0
- package/dist/spectrum/multiSelect/index.d.ts +4 -0
- package/dist/spectrum/multiSelect/index.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/index.js +4 -0
- package/dist/spectrum/multiSelect/index.js.map +1 -0
- package/dist/spectrum/multiSelect/multiSelectUtils.d.ts +53 -0
- package/dist/spectrum/multiSelect/multiSelectUtils.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/multiSelectUtils.js +166 -0
- package/dist/spectrum/multiSelect/multiSelectUtils.js.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectFilter.d.ts +27 -0
- package/dist/spectrum/multiSelect/useMultiSelectFilter.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectFilter.js +51 -0
- package/dist/spectrum/multiSelect/useMultiSelectFilter.js.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectKeyboard.d.ts +40 -0
- package/dist/spectrum/multiSelect/useMultiSelectKeyboard.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectKeyboard.js +200 -0
- package/dist/spectrum/multiSelect/useMultiSelectKeyboard.js.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectLoadingSpinner.d.ts +11 -0
- package/dist/spectrum/multiSelect/useMultiSelectLoadingSpinner.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectLoadingSpinner.js +44 -0
- package/dist/spectrum/multiSelect/useMultiSelectLoadingSpinner.js.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectNormalizedProps.d.ts +21 -0
- package/dist/spectrum/multiSelect/useMultiSelectNormalizedProps.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectNormalizedProps.js +83 -0
- package/dist/spectrum/multiSelect/useMultiSelectNormalizedProps.js.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectScrollListener.d.ts +17 -0
- package/dist/spectrum/multiSelect/useMultiSelectScrollListener.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectScrollListener.js +55 -0
- package/dist/spectrum/multiSelect/useMultiSelectScrollListener.js.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectState.d.ts +26 -0
- package/dist/spectrum/multiSelect/useMultiSelectState.d.ts.map +1 -0
- package/dist/spectrum/multiSelect/useMultiSelectState.js +67 -0
- package/dist/spectrum/multiSelect/useMultiSelectState.js.map +1 -0
- package/dist/spectrum/picker/Picker.d.ts +1 -1
- package/dist/spectrum/picker/PickerProps.d.ts +1 -1
- package/dist/spectrum/picker/PickerProps.d.ts.map +1 -1
- package/dist/spectrum/picker/PickerProps.js.map +1 -1
- package/dist/spectrum/picker/usePickerProps.js +1 -1
- package/dist/spectrum/picker/usePickerProps.js.map +1 -1
- package/dist/spectrum/utils/itemWrapperUtils.d.ts +1 -1
- package/dist/spectrum/utils/itemWrapperUtils.d.ts.map +1 -1
- package/dist/spectrum/utils/itemWrapperUtils.js +3 -0
- package/dist/spectrum/utils/itemWrapperUtils.js.map +1 -1
- package/dist/spectrum/utils/useStringifiedMultiSelection.d.ts.map +1 -1
- package/dist/spectrum/utils/useStringifiedMultiSelection.js +12 -1
- package/dist/spectrum/utils/useStringifiedMultiSelection.js.map +1 -1
- package/package.json +9 -2
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
var _excluded = ["children", "tooltip", "selectedKeys", "defaultSelectedKeys", "disabledKeys", "onChange", "onSelectionChange", "onOpenChange", "onScroll", "label", "description", "errorMessage", "isRequired", "isDisabled", "isReadOnly", "validationState", "isQuiet", "labelPosition", "labelAlign", "necessityIndicator", "contextualHelp", "inputValue", "defaultInputValue", "onInputChange", "shouldFocusWrap", "loadingState", "menuTrigger", "align", "direction", "shouldFlip", "menuWidth", "allowsCustomValue", "formValue", "validationBehavior", "autoFocus", "name", "id", "isHidden", "onFocus", "onBlur", "onFocusChange", "onKeyDown", "onKeyUp", "onSearchTextChange", "selectedItemLabels", "UNSAFE_className", "aria-label", "aria-labelledby", "aria-describedby", "aria-details"];
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
8
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
9
|
+
import React, { useCallback, useId, useMemo, useRef } from 'react';
|
|
10
|
+
import { Field } from '@react-spectrum/label';
|
|
11
|
+
import { FocusRing } from '@react-aria/focus';
|
|
12
|
+
import { Popover } from '@react-spectrum/overlays';
|
|
13
|
+
import { useUnwrapDOMRef } from '@react-spectrum/utils';
|
|
14
|
+
import { useOverlayTriggerState } from '@react-stately/overlays';
|
|
15
|
+
import ChevronDownMedium from '@spectrum-icons/ui/ChevronDownMedium';
|
|
16
|
+
import AlertMedium from '@spectrum-icons/ui/AlertMedium';
|
|
17
|
+
import { ProgressCircle } from '@adobe/react-spectrum';
|
|
18
|
+
import cl from 'classnames';
|
|
19
|
+
import { EMPTY_FUNCTION, ensureArray } from '@deephaven/utils';
|
|
20
|
+
import { useMergeRef } from '@deephaven/react-hooks';
|
|
21
|
+
import { normalizeTooltipOptions, wrapItemChildren } from "../utils/index.js";
|
|
22
|
+
import { flattenJsxChildren, flattenEntriesToItems } from "./multiSelectUtils.js";
|
|
23
|
+
import { useMultiSelectState } from "./useMultiSelectState.js";
|
|
24
|
+
import { useMultiSelectFilter } from "./useMultiSelectFilter.js";
|
|
25
|
+
import { useMultiSelectKeyboard } from "./useMultiSelectKeyboard.js";
|
|
26
|
+
import { useMultiSelectLoadingSpinner } from "./useMultiSelectLoadingSpinner.js";
|
|
27
|
+
import { useMultiSelectScrollListener } from "./useMultiSelectScrollListener.js";
|
|
28
|
+
import { MultiSelectTag } from "./MultiSelectTag.js";
|
|
29
|
+
import { MultiSelectListBox } from "./MultiSelectListBox.js";
|
|
30
|
+
import "./MultiSelect.css";
|
|
31
|
+
/**
|
|
32
|
+
* Convert a Spectrum dimension value (e.g. `"size-3000"`) to its CSS variable
|
|
33
|
+
* form. Numbers are converted to px. Already-valid CSS strings pass through.
|
|
34
|
+
*/
|
|
35
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
36
|
+
function toCssDimension(value) {
|
|
37
|
+
if (value == null) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
if (typeof value === 'number') {
|
|
41
|
+
return "".concat(value, "px");
|
|
42
|
+
}
|
|
43
|
+
if (/^(size|static-size)-/.test(value)) {
|
|
44
|
+
return "var(--spectrum-global-dimension-".concat(value, ")");
|
|
45
|
+
}
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Multi-select styled to match Spectrum ComboBox. Renders selected items as
|
|
51
|
+
* tags inside the trigger area alongside a filter input. Accepts the same
|
|
52
|
+
* `Item` / `Section` JSX children as `Picker`.
|
|
53
|
+
*/
|
|
54
|
+
function MultiSelectInner(props, forwardedRef) {
|
|
55
|
+
var _ref2, _toCssDimension, _triggerRef$current2;
|
|
56
|
+
var {
|
|
57
|
+
children,
|
|
58
|
+
tooltip = true,
|
|
59
|
+
selectedKeys: propSelectedKeys,
|
|
60
|
+
defaultSelectedKeys,
|
|
61
|
+
disabledKeys: propDisabledKeys,
|
|
62
|
+
onChange: propOnChange,
|
|
63
|
+
onSelectionChange: propOnSelectionChange,
|
|
64
|
+
onOpenChange,
|
|
65
|
+
onScroll = EMPTY_FUNCTION,
|
|
66
|
+
label,
|
|
67
|
+
description,
|
|
68
|
+
errorMessage,
|
|
69
|
+
isRequired = false,
|
|
70
|
+
isDisabled = false,
|
|
71
|
+
isReadOnly = false,
|
|
72
|
+
validationState,
|
|
73
|
+
isQuiet = false,
|
|
74
|
+
labelPosition = 'top',
|
|
75
|
+
labelAlign,
|
|
76
|
+
necessityIndicator,
|
|
77
|
+
contextualHelp,
|
|
78
|
+
inputValue: controlledInputValue,
|
|
79
|
+
defaultInputValue = '',
|
|
80
|
+
onInputChange,
|
|
81
|
+
shouldFocusWrap = false,
|
|
82
|
+
loadingState,
|
|
83
|
+
menuTrigger = 'input',
|
|
84
|
+
align = 'start',
|
|
85
|
+
direction = 'bottom',
|
|
86
|
+
shouldFlip = true,
|
|
87
|
+
menuWidth,
|
|
88
|
+
allowsCustomValue = false,
|
|
89
|
+
formValue = 'key',
|
|
90
|
+
validationBehavior = 'aria',
|
|
91
|
+
autoFocus = false,
|
|
92
|
+
name,
|
|
93
|
+
id,
|
|
94
|
+
isHidden = false,
|
|
95
|
+
onFocus,
|
|
96
|
+
onBlur,
|
|
97
|
+
onFocusChange,
|
|
98
|
+
onKeyDown,
|
|
99
|
+
onKeyUp,
|
|
100
|
+
onSearchTextChange,
|
|
101
|
+
selectedItemLabels,
|
|
102
|
+
UNSAFE_className,
|
|
103
|
+
'aria-label': ariaLabel,
|
|
104
|
+
'aria-labelledby': ariaLabelledby,
|
|
105
|
+
'aria-describedby': ariaDescribedby,
|
|
106
|
+
'aria-details': ariaDetails
|
|
107
|
+
} = props,
|
|
108
|
+
styleProps = _objectWithoutProperties(props, _excluded);
|
|
109
|
+
|
|
110
|
+
// Spectrum's onOpenChange omits the trigger reason; relay it via ref.
|
|
111
|
+
var lastTriggerReasonRef = useRef(undefined);
|
|
112
|
+
var handleOverlayOpenChange = useCallback(isOpen => {
|
|
113
|
+
onOpenChange === null || onOpenChange === void 0 || onOpenChange(isOpen, lastTriggerReasonRef.current);
|
|
114
|
+
}, [onOpenChange]);
|
|
115
|
+
var overlayState = useOverlayTriggerState({
|
|
116
|
+
onOpenChange: handleOverlayOpenChange
|
|
117
|
+
});
|
|
118
|
+
var openOverlay = useCallback(reason => {
|
|
119
|
+
lastTriggerReasonRef.current = reason;
|
|
120
|
+
overlayState.open();
|
|
121
|
+
}, [overlayState]);
|
|
122
|
+
var closeOverlay = useCallback(() => {
|
|
123
|
+
lastTriggerReasonRef.current = undefined;
|
|
124
|
+
overlayState.close();
|
|
125
|
+
}, [overlayState]);
|
|
126
|
+
var listBoxId = useId();
|
|
127
|
+
var placement = "".concat(direction, " ").concat(align);
|
|
128
|
+
var triggerRef = useRef(null);
|
|
129
|
+
var inputRef = useRef(null);
|
|
130
|
+
var popoverRef = useRef(null);
|
|
131
|
+
var unwrappedPopoverRef = useUnwrapDOMRef(popoverRef);
|
|
132
|
+
var listBoxRef = useRef(null);
|
|
133
|
+
var unwrappedListBoxRef = useUnwrapDOMRef(listBoxRef);
|
|
134
|
+
var isFocusedRef = useRef(false);
|
|
135
|
+
var mergedTriggerRef = useMergeRef(triggerRef, forwardedRef);
|
|
136
|
+
|
|
137
|
+
// Ensures Item/ItemContent wrapping for tooltips/overflow.
|
|
138
|
+
var tooltipOptions = useMemo(() => normalizeTooltipOptions(tooltip), [tooltip]);
|
|
139
|
+
var wrappedChildren = useMemo(() => ensureArray(wrapItemChildren(children, tooltipOptions)), [children, tooltipOptions]);
|
|
140
|
+
|
|
141
|
+
// Flat {key,label} entries for filter/keyboard hooks. ListBox renders JSX directly.
|
|
142
|
+
var allEntries = useMemo(() => flattenJsxChildren(wrappedChildren), [wrappedChildren]);
|
|
143
|
+
var allItems = useMemo(() => flattenEntriesToItems(allEntries), [allEntries]);
|
|
144
|
+
var allKeys = useMemo(() => allItems.map(i => i.key), [allItems]);
|
|
145
|
+
|
|
146
|
+
// Persistent label cache: accumulates labels from items as they appear in
|
|
147
|
+
// children. When server-side search filters items out of the children, the
|
|
148
|
+
// cache ensures tags still display the correct label.
|
|
149
|
+
var labelCacheRef = useRef(new Map());
|
|
150
|
+
var itemLabelMap = useMemo(() => {
|
|
151
|
+
var cache = labelCacheRef.current;
|
|
152
|
+
allItems.forEach(i => cache.set(i.key, i.label));
|
|
153
|
+
return new Map(cache);
|
|
154
|
+
}, [allItems]);
|
|
155
|
+
var getLabelFor = useCallback(key => {
|
|
156
|
+
var _ref, _itemLabelMap$get;
|
|
157
|
+
return (_ref = (_itemLabelMap$get = itemLabelMap.get(key)) !== null && _itemLabelMap$get !== void 0 ? _itemLabelMap$get : selectedItemLabels === null || selectedItemLabels === void 0 ? void 0 : selectedItemLabels.get(key)) !== null && _ref !== void 0 ? _ref : key;
|
|
158
|
+
}, [itemLabelMap, selectedItemLabels]);
|
|
159
|
+
var {
|
|
160
|
+
searchText,
|
|
161
|
+
setSearchText,
|
|
162
|
+
filteredItems,
|
|
163
|
+
filteredJsxChildren
|
|
164
|
+
} = useMultiSelectFilter({
|
|
165
|
+
allEntries,
|
|
166
|
+
wrappedChildren,
|
|
167
|
+
inputValue: controlledInputValue,
|
|
168
|
+
defaultInputValue,
|
|
169
|
+
onInputChange,
|
|
170
|
+
onSearchTextChange
|
|
171
|
+
});
|
|
172
|
+
var emptyMessage = useMemo(() => {
|
|
173
|
+
if (filteredItems.length > 0) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
if (loadingState === 'loading') {
|
|
177
|
+
return 'Loading...';
|
|
178
|
+
}
|
|
179
|
+
// loadingMore + empty: defer to ListBox's loader pill instead of "No results".
|
|
180
|
+
if (loadingState === 'loadingMore') {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
return 'No results';
|
|
184
|
+
}, [filteredItems.length, loadingState]);
|
|
185
|
+
var {
|
|
186
|
+
selectedKeys,
|
|
187
|
+
selectedKeyArray,
|
|
188
|
+
listBoxDisabledKeys,
|
|
189
|
+
toggleKey,
|
|
190
|
+
applyListBoxSelection
|
|
191
|
+
} = useMultiSelectState({
|
|
192
|
+
selectedKeys: propSelectedKeys,
|
|
193
|
+
defaultSelectedKeys,
|
|
194
|
+
disabledKeys: propDisabledKeys,
|
|
195
|
+
onChange: propOnChange,
|
|
196
|
+
onSelectionChange: propOnSelectionChange,
|
|
197
|
+
allKeys
|
|
198
|
+
});
|
|
199
|
+
var {
|
|
200
|
+
handleInputKeyDown
|
|
201
|
+
} = useMultiSelectKeyboard({
|
|
202
|
+
filteredItems,
|
|
203
|
+
allItems,
|
|
204
|
+
shouldFocusWrap,
|
|
205
|
+
overlayState,
|
|
206
|
+
openOverlay,
|
|
207
|
+
closeOverlay,
|
|
208
|
+
isReadOnly,
|
|
209
|
+
isDisabled,
|
|
210
|
+
searchText,
|
|
211
|
+
setSearchText,
|
|
212
|
+
selectedKeys,
|
|
213
|
+
toggleKey,
|
|
214
|
+
allowsCustomValue,
|
|
215
|
+
menuTrigger,
|
|
216
|
+
onKeyDown,
|
|
217
|
+
listBoxContainerRef: unwrappedListBoxRef,
|
|
218
|
+
inputRef
|
|
219
|
+
});
|
|
220
|
+
useMultiSelectScrollListener({
|
|
221
|
+
containerRef: unwrappedListBoxRef,
|
|
222
|
+
isOpen: overlayState.isOpen,
|
|
223
|
+
onScroll
|
|
224
|
+
});
|
|
225
|
+
var shouldShowInlineSpinner = useMultiSelectLoadingSpinner({
|
|
226
|
+
loadingState,
|
|
227
|
+
searchText,
|
|
228
|
+
isOpen: overlayState.isOpen,
|
|
229
|
+
menuTrigger
|
|
230
|
+
});
|
|
231
|
+
var refocusInput = useCallback(() => {
|
|
232
|
+
requestAnimationFrame(() => {
|
|
233
|
+
var _inputRef$current;
|
|
234
|
+
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
|
|
235
|
+
});
|
|
236
|
+
}, []);
|
|
237
|
+
var handleTagRemove = useCallback(key => {
|
|
238
|
+
toggleKey(key);
|
|
239
|
+
refocusInput();
|
|
240
|
+
}, [toggleKey, refocusInput]);
|
|
241
|
+
var handleListBoxSelectionChange = useCallback(selection => {
|
|
242
|
+
if (isReadOnly) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
applyListBoxSelection(selection, filteredItems);
|
|
246
|
+
refocusInput();
|
|
247
|
+
}, [isReadOnly, applyListBoxSelection, filteredItems, refocusInput]);
|
|
248
|
+
var handleInputFocus = useCallback(e => {
|
|
249
|
+
if (isFocusedRef.current) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
isFocusedRef.current = true;
|
|
253
|
+
if (menuTrigger === 'focus' && !overlayState.isOpen && !isDisabled) {
|
|
254
|
+
openOverlay('focus');
|
|
255
|
+
}
|
|
256
|
+
onFocus === null || onFocus === void 0 || onFocus(e);
|
|
257
|
+
onFocusChange === null || onFocusChange === void 0 || onFocusChange(true);
|
|
258
|
+
}, [onFocus, onFocusChange, menuTrigger, overlayState, isDisabled, openOverlay]);
|
|
259
|
+
var handleInputBlur = useCallback(e => {
|
|
260
|
+
var related = e.relatedTarget;
|
|
261
|
+
if (related != null) {
|
|
262
|
+
if (triggerRef.current != null && triggerRef.current.contains(related)) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (unwrappedPopoverRef.current != null && unwrappedPopoverRef.current.contains(related)) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
// relatedTarget can be null when clicking non-focusable content.
|
|
270
|
+
// Use rAF to check if focus moved back into the component.
|
|
271
|
+
requestAnimationFrame(() => {
|
|
272
|
+
var active = document.activeElement;
|
|
273
|
+
if (active != null && (triggerRef.current != null && triggerRef.current.contains(active) || unwrappedPopoverRef.current != null && unwrappedPopoverRef.current.contains(active))) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
isFocusedRef.current = false;
|
|
277
|
+
if (overlayState.isOpen) {
|
|
278
|
+
closeOverlay();
|
|
279
|
+
}
|
|
280
|
+
onBlur === null || onBlur === void 0 || onBlur(e);
|
|
281
|
+
onFocusChange === null || onFocusChange === void 0 || onFocusChange(false);
|
|
282
|
+
});
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
isFocusedRef.current = false;
|
|
286
|
+
if (overlayState.isOpen) {
|
|
287
|
+
closeOverlay();
|
|
288
|
+
}
|
|
289
|
+
onBlur === null || onBlur === void 0 || onBlur(e);
|
|
290
|
+
onFocusChange === null || onFocusChange === void 0 || onFocusChange(false);
|
|
291
|
+
}, [onBlur, onFocusChange, overlayState, closeOverlay, unwrappedPopoverRef]);
|
|
292
|
+
var handleTriggerAreaClick = useCallback(() => {
|
|
293
|
+
var _inputRef$current2;
|
|
294
|
+
if (isDisabled) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (!overlayState.isOpen) {
|
|
298
|
+
openOverlay('manual');
|
|
299
|
+
}
|
|
300
|
+
(_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 || _inputRef$current2.focus();
|
|
301
|
+
}, [isDisabled, overlayState, openOverlay]);
|
|
302
|
+
var handleChevronClick = useCallback(e => {
|
|
303
|
+
var _inputRef$current3;
|
|
304
|
+
// Stop trigger-area handler from re-opening the popover on close.
|
|
305
|
+
e.stopPropagation();
|
|
306
|
+
if (isDisabled) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
if (overlayState.isOpen) {
|
|
310
|
+
closeOverlay();
|
|
311
|
+
} else {
|
|
312
|
+
openOverlay('manual');
|
|
313
|
+
}
|
|
314
|
+
(_inputRef$current3 = inputRef.current) === null || _inputRef$current3 === void 0 || _inputRef$current3.focus();
|
|
315
|
+
}, [isDisabled, overlayState, openOverlay, closeOverlay]);
|
|
316
|
+
return /*#__PURE__*/_jsx(Field
|
|
317
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
318
|
+
, _objectSpread(_objectSpread({}, styleProps), {}, {
|
|
319
|
+
label: label,
|
|
320
|
+
description: description,
|
|
321
|
+
errorMessage: validationState === 'invalid' ? errorMessage : undefined,
|
|
322
|
+
isRequired: isRequired,
|
|
323
|
+
isDisabled: isDisabled,
|
|
324
|
+
validationState: validationState,
|
|
325
|
+
labelPosition: labelPosition,
|
|
326
|
+
labelAlign: labelAlign,
|
|
327
|
+
necessityIndicator: necessityIndicator,
|
|
328
|
+
contextualHelp: contextualHelp,
|
|
329
|
+
wrapperClassName: cl('dh-multi-select', UNSAFE_className),
|
|
330
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
331
|
+
style: isHidden ? {
|
|
332
|
+
display: 'none'
|
|
333
|
+
} : undefined,
|
|
334
|
+
children: [/*#__PURE__*/_jsx(FocusRing, {
|
|
335
|
+
within: true,
|
|
336
|
+
focusRingClass: "focus-ring",
|
|
337
|
+
focusClass: "is-focused",
|
|
338
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
339
|
+
ref: mergedTriggerRef,
|
|
340
|
+
id: id,
|
|
341
|
+
onClick: handleTriggerAreaClick,
|
|
342
|
+
className: cl('dh-multi-select-trigger', {
|
|
343
|
+
'is-disabled': isDisabled,
|
|
344
|
+
'is-read-only': isReadOnly,
|
|
345
|
+
'is-quiet': isQuiet,
|
|
346
|
+
'is-invalid': validationState === 'invalid'
|
|
347
|
+
}),
|
|
348
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
349
|
+
className: "dh-multi-select-content",
|
|
350
|
+
children: [selectedKeyArray.map(key => /*#__PURE__*/_jsx(MultiSelectTag, {
|
|
351
|
+
tagKey: key,
|
|
352
|
+
label: getLabelFor(key),
|
|
353
|
+
isDisabled: isDisabled,
|
|
354
|
+
isReadOnly: isReadOnly,
|
|
355
|
+
onRemove: handleTagRemove
|
|
356
|
+
}, key)), /*#__PURE__*/_jsx("input", {
|
|
357
|
+
ref: inputRef,
|
|
358
|
+
className: "dh-multi-select-input",
|
|
359
|
+
value: searchText,
|
|
360
|
+
onChange: e => setSearchText(e.target.value),
|
|
361
|
+
onFocus: handleInputFocus,
|
|
362
|
+
onBlur: handleInputBlur,
|
|
363
|
+
onKeyDown: handleInputKeyDown,
|
|
364
|
+
onKeyUp: onKeyUp,
|
|
365
|
+
disabled: isDisabled,
|
|
366
|
+
readOnly: isReadOnly
|
|
367
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
368
|
+
,
|
|
369
|
+
autoFocus: autoFocus,
|
|
370
|
+
role: "combobox",
|
|
371
|
+
"aria-haspopup": "listbox",
|
|
372
|
+
"aria-expanded": overlayState.isOpen,
|
|
373
|
+
"aria-controls": overlayState.isOpen ? listBoxId : undefined,
|
|
374
|
+
"aria-autocomplete": "list",
|
|
375
|
+
"aria-label": ariaLabel,
|
|
376
|
+
"aria-labelledby": ariaLabelledby,
|
|
377
|
+
"aria-describedby": ariaDescribedby,
|
|
378
|
+
"aria-details": ariaDetails
|
|
379
|
+
})]
|
|
380
|
+
}), shouldShowInlineSpinner && /*#__PURE__*/_jsx("div", {
|
|
381
|
+
className: "dh-multi-select-loading-circle",
|
|
382
|
+
children: /*#__PURE__*/_jsx(ProgressCircle, {
|
|
383
|
+
"aria-label": "Loading",
|
|
384
|
+
isIndeterminate: true,
|
|
385
|
+
size: "S"
|
|
386
|
+
})
|
|
387
|
+
}), validationState === 'invalid' && !isDisabled && /*#__PURE__*/_jsx("div", {
|
|
388
|
+
className: "dh-multi-select-invalid-icon",
|
|
389
|
+
"aria-hidden": "true",
|
|
390
|
+
children: /*#__PURE__*/_jsx(AlertMedium, {})
|
|
391
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
392
|
+
className: cl('dh-multi-select-chevron', {
|
|
393
|
+
'is-open': overlayState.isOpen
|
|
394
|
+
}),
|
|
395
|
+
onClick: handleChevronClick
|
|
396
|
+
// Suppress default to keep input focus on chevron click.
|
|
397
|
+
,
|
|
398
|
+
onPointerDown: e => e.preventDefault(),
|
|
399
|
+
role: "button",
|
|
400
|
+
tabIndex: -1,
|
|
401
|
+
"aria-label": "Toggle dropdown",
|
|
402
|
+
children: /*#__PURE__*/_jsx(ChevronDownMedium, {})
|
|
403
|
+
})]
|
|
404
|
+
})
|
|
405
|
+
}), name != null && /*#__PURE__*/_jsx("input", {
|
|
406
|
+
type: "hidden",
|
|
407
|
+
name: name,
|
|
408
|
+
value: formValue === 'text' ? selectedKeyArray.map(getLabelFor).join(',') : selectedKeyArray.join(','),
|
|
409
|
+
required: validationBehavior === 'native' && isRequired ? true : undefined
|
|
410
|
+
}), overlayState.isOpen && !isDisabled && /*#__PURE__*/_jsx(Popover, {
|
|
411
|
+
ref: popoverRef,
|
|
412
|
+
triggerRef: triggerRef,
|
|
413
|
+
state: overlayState,
|
|
414
|
+
hideArrow: true,
|
|
415
|
+
isNonModal: true,
|
|
416
|
+
placement: placement,
|
|
417
|
+
shouldFlip: shouldFlip,
|
|
418
|
+
shouldCloseOnInteractOutside: target => {
|
|
419
|
+
var _triggerRef$current;
|
|
420
|
+
return ((_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : _triggerRef$current.contains(target)) !== true;
|
|
421
|
+
},
|
|
422
|
+
UNSAFE_style: {
|
|
423
|
+
width: (_ref2 = (_toCssDimension = toCssDimension(menuWidth)) !== null && _toCssDimension !== void 0 ? _toCssDimension : (_triggerRef$current2 = triggerRef.current) === null || _triggerRef$current2 === void 0 ? void 0 : _triggerRef$current2.offsetWidth) !== null && _ref2 !== void 0 ? _ref2 : undefined
|
|
424
|
+
},
|
|
425
|
+
children: /*#__PURE__*/_jsx(MultiSelectListBox, {
|
|
426
|
+
listBoxRef: listBoxRef,
|
|
427
|
+
listBoxId: listBoxId,
|
|
428
|
+
loadingState: loadingState,
|
|
429
|
+
selectedKeys: selectedKeys,
|
|
430
|
+
disabledKeys: listBoxDisabledKeys,
|
|
431
|
+
onSelectionChange: handleListBoxSelectionChange,
|
|
432
|
+
ariaLabel: typeof label === 'string' ? label : 'Options',
|
|
433
|
+
emptyMessage: emptyMessage,
|
|
434
|
+
children: filteredJsxChildren
|
|
435
|
+
})
|
|
436
|
+
})]
|
|
437
|
+
})
|
|
438
|
+
}));
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/** Forwarded-ref wrapper. Trigger is a <div>, matching Picker's DOMRef shape. */
|
|
442
|
+
export var MultiSelect = /*#__PURE__*/React.forwardRef(MultiSelectInner);
|
|
443
|
+
MultiSelect.displayName = 'MultiSelect';
|
|
444
|
+
export default MultiSelect;
|
|
445
|
+
//# sourceMappingURL=MultiSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiSelect.js","names":["React","useCallback","useId","useMemo","useRef","Field","FocusRing","Popover","useUnwrapDOMRef","useOverlayTriggerState","ChevronDownMedium","AlertMedium","ProgressCircle","cl","EMPTY_FUNCTION","ensureArray","useMergeRef","normalizeTooltipOptions","wrapItemChildren","flattenJsxChildren","flattenEntriesToItems","useMultiSelectState","useMultiSelectFilter","useMultiSelectKeyboard","useMultiSelectLoadingSpinner","useMultiSelectScrollListener","MultiSelectTag","MultiSelectListBox","jsx","_jsx","jsxs","_jsxs","toCssDimension","value","undefined","concat","test","MultiSelectInner","props","forwardedRef","_ref2","_toCssDimension","_triggerRef$current2","children","tooltip","selectedKeys","propSelectedKeys","defaultSelectedKeys","disabledKeys","propDisabledKeys","onChange","propOnChange","onSelectionChange","propOnSelectionChange","onOpenChange","onScroll","label","description","errorMessage","isRequired","isDisabled","isReadOnly","validationState","isQuiet","labelPosition","labelAlign","necessityIndicator","contextualHelp","inputValue","controlledInputValue","defaultInputValue","onInputChange","shouldFocusWrap","loadingState","menuTrigger","align","direction","shouldFlip","menuWidth","allowsCustomValue","formValue","validationBehavior","autoFocus","name","id","isHidden","onFocus","onBlur","onFocusChange","onKeyDown","onKeyUp","onSearchTextChange","selectedItemLabels","UNSAFE_className","ariaLabel","ariaLabelledby","ariaDescribedby","ariaDetails","styleProps","_objectWithoutProperties","_excluded","lastTriggerReasonRef","handleOverlayOpenChange","isOpen","current","overlayState","openOverlay","reason","open","closeOverlay","close","listBoxId","placement","triggerRef","inputRef","popoverRef","unwrappedPopoverRef","listBoxRef","unwrappedListBoxRef","isFocusedRef","mergedTriggerRef","tooltipOptions","wrappedChildren","allEntries","allItems","allKeys","map","i","key","labelCacheRef","Map","itemLabelMap","cache","forEach","set","getLabelFor","_ref","_itemLabelMap$get","get","searchText","setSearchText","filteredItems","filteredJsxChildren","emptyMessage","length","selectedKeyArray","listBoxDisabledKeys","toggleKey","applyListBoxSelection","handleInputKeyDown","listBoxContainerRef","containerRef","shouldShowInlineSpinner","refocusInput","requestAnimationFrame","_inputRef$current","focus","handleTagRemove","handleListBoxSelectionChange","selection","handleInputFocus","e","handleInputBlur","related","relatedTarget","contains","active","document","activeElement","handleTriggerAreaClick","_inputRef$current2","handleChevronClick","_inputRef$current3","stopPropagation","_objectSpread","wrapperClassName","style","display","within","focusRingClass","focusClass","ref","onClick","className","tagKey","onRemove","target","disabled","readOnly","role","isIndeterminate","size","onPointerDown","preventDefault","tabIndex","type","join","required","state","hideArrow","isNonModal","shouldCloseOnInteractOutside","_triggerRef$current","UNSAFE_style","width","offsetWidth","MultiSelect","forwardRef","displayName"],"sources":["../../../src/spectrum/multiSelect/MultiSelect.tsx"],"sourcesContent":["import React, { useCallback, useId, useMemo, useRef } from 'react';\nimport type { DOMRefValue } from '@react-types/shared';\nimport type { Placement } from '@react-types/overlays';\nimport { Field } from '@react-spectrum/label';\nimport { FocusRing } from '@react-aria/focus';\nimport { Popover } from '@react-spectrum/overlays';\nimport { useUnwrapDOMRef } from '@react-spectrum/utils';\nimport { useOverlayTriggerState } from '@react-stately/overlays';\nimport ChevronDownMedium from '@spectrum-icons/ui/ChevronDownMedium';\nimport AlertMedium from '@spectrum-icons/ui/AlertMedium';\nimport { ProgressCircle } from '@adobe/react-spectrum';\nimport cl from 'classnames';\nimport { EMPTY_FUNCTION, ensureArray } from '@deephaven/utils';\nimport { useMergeRef } from '@deephaven/react-hooks';\nimport { normalizeTooltipOptions, wrapItemChildren } from '../utils';\nimport type { MenuTriggerAction } from '../comboBox';\nimport { type MultiSelectProps } from './MultiSelectProps';\nimport {\n flattenJsxChildren,\n flattenEntriesToItems,\n type MultiSelectFlatEntry,\n} from './multiSelectUtils';\nimport { useMultiSelectState } from './useMultiSelectState';\nimport { useMultiSelectFilter } from './useMultiSelectFilter';\nimport { useMultiSelectKeyboard } from './useMultiSelectKeyboard';\nimport { useMultiSelectLoadingSpinner } from './useMultiSelectLoadingSpinner';\nimport { useMultiSelectScrollListener } from './useMultiSelectScrollListener';\nimport { MultiSelectTag } from './MultiSelectTag';\nimport { MultiSelectListBox } from './MultiSelectListBox';\nimport './MultiSelect.scss';\n\n/**\n * Convert a Spectrum dimension value (e.g. `\"size-3000\"`) to its CSS variable\n * form. Numbers are converted to px. Already-valid CSS strings pass through.\n */\nfunction toCssDimension(\n value: string | number | undefined\n): string | undefined {\n if (value == null) {\n return undefined;\n }\n if (typeof value === 'number') {\n return `${value}px`;\n }\n if (/^(size|static-size)-/.test(value)) {\n return `var(--spectrum-global-dimension-${value})`;\n }\n return value;\n}\n\n/**\n * Multi-select styled to match Spectrum ComboBox. Renders selected items as\n * tags inside the trigger area alongside a filter input. Accepts the same\n * `Item` / `Section` JSX children as `Picker`.\n */\nfunction MultiSelectInner(\n props: MultiSelectProps,\n forwardedRef: React.Ref<HTMLDivElement>\n): JSX.Element {\n const {\n children,\n tooltip = true,\n selectedKeys: propSelectedKeys,\n defaultSelectedKeys,\n disabledKeys: propDisabledKeys,\n onChange: propOnChange,\n onSelectionChange: propOnSelectionChange,\n onOpenChange,\n onScroll = EMPTY_FUNCTION,\n label,\n description,\n errorMessage,\n isRequired = false,\n isDisabled = false,\n isReadOnly = false,\n validationState,\n isQuiet = false,\n labelPosition = 'top',\n labelAlign,\n necessityIndicator,\n contextualHelp,\n inputValue: controlledInputValue,\n defaultInputValue = '',\n onInputChange,\n shouldFocusWrap = false,\n loadingState,\n menuTrigger = 'input',\n align = 'start',\n direction = 'bottom',\n shouldFlip = true,\n menuWidth,\n allowsCustomValue = false,\n formValue = 'key',\n validationBehavior = 'aria',\n autoFocus = false,\n name,\n id,\n isHidden = false,\n onFocus,\n onBlur,\n onFocusChange,\n onKeyDown,\n onKeyUp,\n onSearchTextChange,\n selectedItemLabels,\n UNSAFE_className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n 'aria-describedby': ariaDescribedby,\n 'aria-details': ariaDetails,\n ...styleProps\n } = props;\n\n // Spectrum's onOpenChange omits the trigger reason; relay it via ref.\n const lastTriggerReasonRef = useRef<MenuTriggerAction | undefined>(undefined);\n\n const handleOverlayOpenChange = useCallback(\n (isOpen: boolean) => {\n onOpenChange?.(isOpen, lastTriggerReasonRef.current);\n },\n [onOpenChange]\n );\n\n const overlayState = useOverlayTriggerState({\n onOpenChange: handleOverlayOpenChange,\n });\n\n const openOverlay = useCallback(\n (reason: MenuTriggerAction) => {\n lastTriggerReasonRef.current = reason;\n overlayState.open();\n },\n [overlayState]\n );\n const closeOverlay = useCallback(() => {\n lastTriggerReasonRef.current = undefined;\n overlayState.close();\n }, [overlayState]);\n\n const listBoxId = useId();\n\n const placement = `${direction} ${align}` as Placement;\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const popoverRef = useRef<DOMRefValue<HTMLDivElement>>(null);\n const unwrappedPopoverRef = useUnwrapDOMRef(popoverRef);\n const listBoxRef = useRef<DOMRefValue<HTMLDivElement>>(null);\n const unwrappedListBoxRef = useUnwrapDOMRef(listBoxRef);\n const isFocusedRef = useRef(false);\n const mergedTriggerRef = useMergeRef(triggerRef, forwardedRef);\n\n // Ensures Item/ItemContent wrapping for tooltips/overflow.\n const tooltipOptions = useMemo(\n () => normalizeTooltipOptions(tooltip),\n [tooltip]\n );\n const wrappedChildren = useMemo(\n () => ensureArray(wrapItemChildren(children, tooltipOptions)),\n [children, tooltipOptions]\n );\n\n // Flat {key,label} entries for filter/keyboard hooks. ListBox renders JSX directly.\n const allEntries: MultiSelectFlatEntry[] = useMemo(\n () => flattenJsxChildren(wrappedChildren),\n [wrappedChildren]\n );\n\n const allItems = useMemo(\n () => flattenEntriesToItems(allEntries),\n [allEntries]\n );\n const allKeys = useMemo(() => allItems.map(i => i.key), [allItems]);\n\n // Persistent label cache: accumulates labels from items as they appear in\n // children. When server-side search filters items out of the children, the\n // cache ensures tags still display the correct label.\n const labelCacheRef = useRef<Map<string, string>>(new Map());\n const itemLabelMap = useMemo(() => {\n const cache = labelCacheRef.current;\n allItems.forEach(i => cache.set(i.key, i.label));\n return new Map(cache);\n }, [allItems]);\n\n const getLabelFor = useCallback(\n (key: string): string =>\n itemLabelMap.get(key) ?? selectedItemLabels?.get(key) ?? key,\n [itemLabelMap, selectedItemLabels]\n );\n\n const { searchText, setSearchText, filteredItems, filteredJsxChildren } =\n useMultiSelectFilter({\n allEntries,\n wrappedChildren,\n inputValue: controlledInputValue,\n defaultInputValue,\n onInputChange,\n onSearchTextChange,\n });\n\n const emptyMessage: string | undefined = useMemo(() => {\n if (filteredItems.length > 0) {\n return undefined;\n }\n if (loadingState === 'loading') {\n return 'Loading...';\n }\n // loadingMore + empty: defer to ListBox's loader pill instead of \"No results\".\n if (loadingState === 'loadingMore') {\n return undefined;\n }\n return 'No results';\n }, [filteredItems.length, loadingState]);\n\n const {\n selectedKeys,\n selectedKeyArray,\n listBoxDisabledKeys,\n toggleKey,\n applyListBoxSelection,\n } = useMultiSelectState({\n selectedKeys: propSelectedKeys,\n defaultSelectedKeys,\n disabledKeys: propDisabledKeys,\n onChange: propOnChange,\n onSelectionChange: propOnSelectionChange,\n allKeys,\n });\n\n const { handleInputKeyDown } = useMultiSelectKeyboard({\n filteredItems,\n allItems,\n shouldFocusWrap,\n overlayState,\n openOverlay,\n closeOverlay,\n isReadOnly,\n isDisabled,\n searchText,\n setSearchText,\n selectedKeys,\n toggleKey,\n allowsCustomValue,\n menuTrigger,\n onKeyDown,\n listBoxContainerRef: unwrappedListBoxRef,\n inputRef,\n });\n\n useMultiSelectScrollListener({\n containerRef: unwrappedListBoxRef,\n isOpen: overlayState.isOpen,\n onScroll,\n });\n\n const shouldShowInlineSpinner = useMultiSelectLoadingSpinner({\n loadingState,\n searchText,\n isOpen: overlayState.isOpen,\n menuTrigger,\n });\n\n const refocusInput = useCallback(() => {\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n }, []);\n\n const handleTagRemove = useCallback(\n (key: string) => {\n toggleKey(key);\n refocusInput();\n },\n [toggleKey, refocusInput]\n );\n\n const handleListBoxSelectionChange = useCallback(\n (selection: Parameters<typeof applyListBoxSelection>[0]) => {\n if (isReadOnly) {\n return;\n }\n applyListBoxSelection(selection, filteredItems);\n refocusInput();\n },\n [isReadOnly, applyListBoxSelection, filteredItems, refocusInput]\n );\n\n const handleInputFocus = useCallback(\n (e: React.FocusEvent) => {\n if (isFocusedRef.current) {\n return;\n }\n isFocusedRef.current = true;\n if (menuTrigger === 'focus' && !overlayState.isOpen && !isDisabled) {\n openOverlay('focus');\n }\n onFocus?.(e);\n onFocusChange?.(true);\n },\n [onFocus, onFocusChange, menuTrigger, overlayState, isDisabled, openOverlay]\n );\n\n const handleInputBlur = useCallback(\n (e: React.FocusEvent) => {\n const related = e.relatedTarget as HTMLElement | null;\n\n if (related != null) {\n if (\n triggerRef.current != null &&\n triggerRef.current.contains(related)\n ) {\n return;\n }\n if (\n unwrappedPopoverRef.current != null &&\n unwrappedPopoverRef.current.contains(related)\n ) {\n return;\n }\n } else {\n // relatedTarget can be null when clicking non-focusable content.\n // Use rAF to check if focus moved back into the component.\n requestAnimationFrame(() => {\n const active = document.activeElement as HTMLElement | null;\n if (\n active != null &&\n ((triggerRef.current != null &&\n triggerRef.current.contains(active)) ||\n (unwrappedPopoverRef.current != null &&\n unwrappedPopoverRef.current.contains(active)))\n ) {\n return;\n }\n isFocusedRef.current = false;\n if (overlayState.isOpen) {\n closeOverlay();\n }\n onBlur?.(e);\n onFocusChange?.(false);\n });\n return;\n }\n\n isFocusedRef.current = false;\n if (overlayState.isOpen) {\n closeOverlay();\n }\n onBlur?.(e);\n onFocusChange?.(false);\n },\n [onBlur, onFocusChange, overlayState, closeOverlay, unwrappedPopoverRef]\n );\n\n const handleTriggerAreaClick = useCallback(() => {\n if (isDisabled) {\n return;\n }\n if (!overlayState.isOpen) {\n openOverlay('manual');\n }\n inputRef.current?.focus();\n }, [isDisabled, overlayState, openOverlay]);\n\n const handleChevronClick = useCallback(\n (e: React.MouseEvent) => {\n // Stop trigger-area handler from re-opening the popover on close.\n e.stopPropagation();\n if (isDisabled) {\n return;\n }\n if (overlayState.isOpen) {\n closeOverlay();\n } else {\n openOverlay('manual');\n }\n inputRef.current?.focus();\n },\n [isDisabled, overlayState, openOverlay, closeOverlay]\n );\n\n return (\n <Field\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...styleProps}\n label={label}\n description={description}\n errorMessage={validationState === 'invalid' ? errorMessage : undefined}\n isRequired={isRequired}\n isDisabled={isDisabled}\n validationState={validationState}\n labelPosition={labelPosition}\n labelAlign={labelAlign}\n necessityIndicator={necessityIndicator}\n contextualHelp={contextualHelp}\n wrapperClassName={cl('dh-multi-select', UNSAFE_className)}\n >\n <div style={isHidden ? { display: 'none' } : undefined}>\n <FocusRing within focusRingClass=\"focus-ring\" focusClass=\"is-focused\">\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div\n ref={mergedTriggerRef}\n id={id}\n onClick={handleTriggerAreaClick}\n className={cl('dh-multi-select-trigger', {\n 'is-disabled': isDisabled,\n 'is-read-only': isReadOnly,\n 'is-quiet': isQuiet,\n 'is-invalid': validationState === 'invalid',\n })}\n >\n <div className=\"dh-multi-select-content\">\n {selectedKeyArray.map(key => (\n <MultiSelectTag\n key={key}\n tagKey={key}\n label={getLabelFor(key)}\n isDisabled={isDisabled}\n isReadOnly={isReadOnly}\n onRemove={handleTagRemove}\n />\n ))}\n <input\n ref={inputRef}\n className=\"dh-multi-select-input\"\n value={searchText}\n onChange={e => setSearchText(e.target.value)}\n onFocus={handleInputFocus}\n onBlur={handleInputBlur}\n onKeyDown={handleInputKeyDown}\n onKeyUp={onKeyUp}\n disabled={isDisabled}\n readOnly={isReadOnly}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={autoFocus}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={overlayState.isOpen}\n aria-controls={overlayState.isOpen ? listBoxId : undefined}\n aria-autocomplete=\"list\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-describedby={ariaDescribedby}\n aria-details={ariaDetails}\n />\n </div>\n\n {shouldShowInlineSpinner && (\n <div className=\"dh-multi-select-loading-circle\">\n <ProgressCircle aria-label=\"Loading\" isIndeterminate size=\"S\" />\n </div>\n )}\n\n {validationState === 'invalid' && !isDisabled && (\n <div className=\"dh-multi-select-invalid-icon\" aria-hidden=\"true\">\n <AlertMedium />\n </div>\n )}\n\n <div\n className={cl('dh-multi-select-chevron', {\n 'is-open': overlayState.isOpen,\n })}\n onClick={handleChevronClick}\n // Suppress default to keep input focus on chevron click.\n onPointerDown={e => e.preventDefault()}\n role=\"button\"\n tabIndex={-1}\n aria-label=\"Toggle dropdown\"\n >\n <ChevronDownMedium />\n </div>\n </div>\n </FocusRing>\n\n {name != null && (\n <input\n type=\"hidden\"\n name={name}\n value={\n formValue === 'text'\n ? selectedKeyArray.map(getLabelFor).join(',')\n : selectedKeyArray.join(',')\n }\n required={\n validationBehavior === 'native' && isRequired ? true : undefined\n }\n />\n )}\n\n {overlayState.isOpen && !isDisabled && (\n <Popover\n ref={popoverRef}\n triggerRef={triggerRef}\n state={overlayState}\n hideArrow\n isNonModal\n placement={placement}\n shouldFlip={shouldFlip}\n shouldCloseOnInteractOutside={target =>\n triggerRef.current?.contains(target) !== true\n }\n UNSAFE_style={{\n width:\n toCssDimension(menuWidth) ??\n triggerRef.current?.offsetWidth ??\n undefined,\n }}\n >\n <MultiSelectListBox\n listBoxRef={listBoxRef}\n listBoxId={listBoxId}\n loadingState={loadingState}\n selectedKeys={selectedKeys}\n disabledKeys={listBoxDisabledKeys}\n onSelectionChange={handleListBoxSelectionChange}\n ariaLabel={typeof label === 'string' ? label : 'Options'}\n emptyMessage={emptyMessage}\n >\n {filteredJsxChildren}\n </MultiSelectListBox>\n </Popover>\n )}\n </div>\n </Field>\n );\n}\n\n/** Forwarded-ref wrapper. Trigger is a <div>, matching Picker's DOMRef shape. */\nexport const MultiSelect = React.forwardRef(MultiSelectInner);\nMultiSelect.displayName = 'MultiSelect';\n\nexport default MultiSelect;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import type { DOMRef, LoadingState, Selection } from '@react-types/shared';
|
|
3
|
+
export interface MultiSelectListBoxProps {
|
|
4
|
+
/** DOMRef forwarded to the inner Spectrum `<ListBox>`. */
|
|
5
|
+
listBoxRef: DOMRef<HTMLDivElement>;
|
|
6
|
+
/** ID applied to the inner Spectrum `<ListBox>`. */
|
|
7
|
+
listBoxId: string;
|
|
8
|
+
/** Spectrum `LoadingState` for the items collection. */
|
|
9
|
+
loadingState: LoadingState | undefined;
|
|
10
|
+
/** JSX children to render inside `<ListBox>`. */
|
|
11
|
+
children: ReactElement[];
|
|
12
|
+
/** Selected keys */
|
|
13
|
+
selectedKeys: Iterable<string>;
|
|
14
|
+
/** Disabled keys for `<ListBox>`. */
|
|
15
|
+
disabledKeys: Iterable<string> | undefined;
|
|
16
|
+
/** Selection change handler from `<ListBox>`. */
|
|
17
|
+
onSelectionChange: (selection: Selection) => void;
|
|
18
|
+
/** ARIA label applied to the `<ListBox>`. */
|
|
19
|
+
ariaLabel: string;
|
|
20
|
+
/** When provided, the ListBox is replaced with this empty-state message. */
|
|
21
|
+
emptyMessage?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Popover content for `MultiSelect`. Renders either an empty-state message (text-only)
|
|
25
|
+
* or the Spectrum `<ListBox>`. Private subcomponent of `MultiSelect`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function MultiSelectListBox({ listBoxRef, listBoxId, loadingState, children, selectedKeys, disabledKeys, onSelectionChange, ariaLabel, emptyMessage, }: MultiSelectListBoxProps): JSX.Element;
|
|
28
|
+
export default MultiSelectListBox;
|
|
29
|
+
//# sourceMappingURL=MultiSelectListBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiSelectListBox.d.ts","sourceRoot":"","sources":["../../../src/spectrum/multiSelect/MultiSelectListBox.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE3E,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IACnC,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,YAAY,EAAE,YAAY,GAAG,SAAS,CAAC;IACvC,iDAAiD;IACjD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,oBAAoB;IACpB,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,qCAAqC;IACrC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IAC3C,iDAAiD;IACjD,iBAAiB,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;IAClD,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,YAAY,GACb,EAAE,uBAAuB,GAAG,GAAG,CAAC,OAAO,CAoBvC;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ListBox } from '@adobe/react-spectrum';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Popover content for `MultiSelect`. Renders either an empty-state message (text-only)
|
|
5
|
+
* or the Spectrum `<ListBox>`. Private subcomponent of `MultiSelect`.
|
|
6
|
+
*/
|
|
7
|
+
export function MultiSelectListBox(_ref) {
|
|
8
|
+
var {
|
|
9
|
+
listBoxRef,
|
|
10
|
+
listBoxId,
|
|
11
|
+
loadingState,
|
|
12
|
+
children,
|
|
13
|
+
selectedKeys,
|
|
14
|
+
disabledKeys,
|
|
15
|
+
onSelectionChange,
|
|
16
|
+
ariaLabel,
|
|
17
|
+
emptyMessage
|
|
18
|
+
} = _ref;
|
|
19
|
+
if (emptyMessage != null) {
|
|
20
|
+
return /*#__PURE__*/_jsx("div", {
|
|
21
|
+
className: "dh-multi-select-empty",
|
|
22
|
+
children: emptyMessage
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return /*#__PURE__*/_jsx(ListBox, {
|
|
26
|
+
ref: listBoxRef,
|
|
27
|
+
id: listBoxId,
|
|
28
|
+
selectionMode: "multiple",
|
|
29
|
+
selectedKeys: selectedKeys,
|
|
30
|
+
onSelectionChange: onSelectionChange,
|
|
31
|
+
disabledKeys: disabledKeys,
|
|
32
|
+
"aria-label": ariaLabel,
|
|
33
|
+
isLoading: loadingState === 'loadingMore',
|
|
34
|
+
UNSAFE_style: {
|
|
35
|
+
maxHeight: 'inherit'
|
|
36
|
+
},
|
|
37
|
+
children: children
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export default MultiSelectListBox;
|
|
41
|
+
//# sourceMappingURL=MultiSelectListBox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiSelectListBox.js","names":["ListBox","jsx","_jsx","MultiSelectListBox","_ref","listBoxRef","listBoxId","loadingState","children","selectedKeys","disabledKeys","onSelectionChange","ariaLabel","emptyMessage","className","ref","id","selectionMode","isLoading","UNSAFE_style","maxHeight"],"sources":["../../../src/spectrum/multiSelect/MultiSelectListBox.tsx"],"sourcesContent":["import { type ReactElement } from 'react';\nimport { ListBox } from '@adobe/react-spectrum';\nimport type { DOMRef, LoadingState, Selection } from '@react-types/shared';\n\nexport interface MultiSelectListBoxProps {\n /** DOMRef forwarded to the inner Spectrum `<ListBox>`. */\n listBoxRef: DOMRef<HTMLDivElement>;\n /** ID applied to the inner Spectrum `<ListBox>`. */\n listBoxId: string;\n /** Spectrum `LoadingState` for the items collection. */\n loadingState: LoadingState | undefined;\n /** JSX children to render inside `<ListBox>`. */\n children: ReactElement[];\n /** Selected keys */\n selectedKeys: Iterable<string>;\n /** Disabled keys for `<ListBox>`. */\n disabledKeys: Iterable<string> | undefined;\n /** Selection change handler from `<ListBox>`. */\n onSelectionChange: (selection: Selection) => void;\n /** ARIA label applied to the `<ListBox>`. */\n ariaLabel: string;\n /** When provided, the ListBox is replaced with this empty-state message. */\n emptyMessage?: string;\n}\n\n/**\n * Popover content for `MultiSelect`. Renders either an empty-state message (text-only)\n * or the Spectrum `<ListBox>`. Private subcomponent of `MultiSelect`.\n */\nexport function MultiSelectListBox({\n listBoxRef,\n listBoxId,\n loadingState,\n children,\n selectedKeys,\n disabledKeys,\n onSelectionChange,\n ariaLabel,\n emptyMessage,\n}: MultiSelectListBoxProps): JSX.Element {\n if (emptyMessage != null) {\n return <div className=\"dh-multi-select-empty\">{emptyMessage}</div>;\n }\n\n return (\n <ListBox\n ref={listBoxRef}\n id={listBoxId}\n selectionMode=\"multiple\"\n selectedKeys={selectedKeys}\n onSelectionChange={onSelectionChange}\n disabledKeys={disabledKeys}\n aria-label={ariaLabel}\n isLoading={loadingState === 'loadingMore'}\n UNSAFE_style={{ maxHeight: 'inherit' }}\n >\n {children}\n </ListBox>\n );\n}\n\nexport default MultiSelectListBox;\n"],"mappings":"AACA,SAASA,OAAO,QAAQ,uBAAuB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAwBhD;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAAAC,IAAA,EAUO;EAAA,IAVN;IACjCC,UAAU;IACVC,SAAS;IACTC,YAAY;IACZC,QAAQ;IACRC,YAAY;IACZC,YAAY;IACZC,iBAAiB;IACjBC,SAAS;IACTC;EACuB,CAAC,GAAAT,IAAA;EACxB,IAAIS,YAAY,IAAI,IAAI,EAAE;IACxB,oBAAOX,IAAA;MAAKY,SAAS,EAAC,uBAAuB;MAAAN,QAAA,EAAEK;IAAY,CAAM,CAAC;EACpE;EAEA,oBACEX,IAAA,CAACF,OAAO;IACNe,GAAG,EAAEV,UAAW;IAChBW,EAAE,EAAEV,SAAU;IACdW,aAAa,EAAC,UAAU;IACxBR,YAAY,EAAEA,YAAa;IAC3BE,iBAAiB,EAAEA,iBAAkB;IACrCD,YAAY,EAAEA,YAAa;IAC3B,cAAYE,SAAU;IACtBM,SAAS,EAAEX,YAAY,KAAK,aAAc;IAC1CY,YAAY,EAAE;MAAEC,SAAS,EAAE;IAAU,CAAE;IAAAZ,QAAA,EAEtCA;EAAQ,CACF,CAAC;AAEd;AAEA,eAAeL,kBAAkB","ignoreList":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type MultiSelectNormalizedProps } from './MultiSelectProps';
|
|
2
|
+
/**
|
|
3
|
+
* MultiSelect that takes an array of `NormalizedItem` or `NormalizedSection` items as children.
|
|
4
|
+
* Handles converting selection keys and uses `useRenderNormalizedItem` to render items.
|
|
5
|
+
*/
|
|
6
|
+
export declare function MultiSelectNormalized({ UNSAFE_className, ...props }: MultiSelectNormalizedProps): JSX.Element;
|
|
7
|
+
export default MultiSelectNormalized;
|
|
8
|
+
//# sourceMappingURL=MultiSelectNormalized.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiSelectNormalized.d.ts","sourceRoot":"","sources":["../../../src/spectrum/multiSelect/MultiSelectNormalized.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAGrE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,gBAAgB,EAChB,GAAG,KAAK,EACT,EAAE,0BAA0B,GAAG,GAAG,CAAC,OAAO,CAc1C;AAED,eAAe,qBAAqB,CAAC"}
|