@deephaven/components 0.43.0 → 0.44.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 (214) hide show
  1. package/dist/AutoCompleteInput.css +35 -0
  2. package/dist/AutoCompleteInput.css.map +1 -0
  3. package/dist/AutoCompleteInput.js +496 -0
  4. package/dist/AutoCompleteInput.js.map +1 -0
  5. package/dist/AutoResizeTextarea.css +11 -0
  6. package/dist/AutoResizeTextarea.css.map +1 -0
  7. package/dist/AutoResizeTextarea.js +128 -0
  8. package/dist/AutoResizeTextarea.js.map +1 -0
  9. package/dist/BasicModal.js +112 -0
  10. package/dist/BasicModal.js.map +1 -0
  11. package/dist/Button.d.ts +1 -1
  12. package/dist/Button.js +193 -0
  13. package/dist/Button.js.map +1 -0
  14. package/dist/ButtonGroup.js +31 -0
  15. package/dist/ButtonGroup.js.map +1 -0
  16. package/dist/ButtonOld.js +41 -0
  17. package/dist/ButtonOld.js.map +1 -0
  18. package/dist/CardFlip.css +36 -0
  19. package/dist/CardFlip.css.map +1 -0
  20. package/dist/CardFlip.js +61 -0
  21. package/dist/CardFlip.js.map +1 -0
  22. package/dist/Checkbox.js +104 -0
  23. package/dist/Checkbox.js.map +1 -0
  24. package/dist/Collapse.js +89 -0
  25. package/dist/Collapse.js.map +1 -0
  26. package/dist/ComboBox.css +50 -0
  27. package/dist/ComboBox.css.map +1 -0
  28. package/dist/ComboBox.js +487 -0
  29. package/dist/ComboBox.js.map +1 -0
  30. package/dist/CopyButton.js +30 -0
  31. package/dist/CopyButton.js.map +1 -0
  32. package/dist/CustomTimeSelect.css +65 -0
  33. package/dist/CustomTimeSelect.css.map +1 -0
  34. package/dist/CustomTimeSelect.js +516 -0
  35. package/dist/CustomTimeSelect.js.map +1 -0
  36. package/dist/DateInput.js +54 -0
  37. package/dist/DateInput.js.map +1 -0
  38. package/dist/DateInputUtils.js +33 -0
  39. package/dist/DateInputUtils.js.map +1 -0
  40. package/dist/DateTimeInput.js +84 -0
  41. package/dist/DateTimeInput.js.map +1 -0
  42. package/dist/DateTimeInputUtils.js +8 -0
  43. package/dist/DateTimeInputUtils.js.map +1 -0
  44. package/dist/DebouncedSearchInput.js +79 -0
  45. package/dist/DebouncedSearchInput.js.map +1 -0
  46. package/dist/DragUtils.js +68 -0
  47. package/dist/DragUtils.js.map +1 -0
  48. package/dist/DraggableItemList.css +118 -0
  49. package/dist/DraggableItemList.css.map +1 -0
  50. package/dist/DraggableItemList.js +268 -0
  51. package/dist/DraggableItemList.js.map +1 -0
  52. package/dist/EditableItemList.js +105 -0
  53. package/dist/EditableItemList.js.map +1 -0
  54. package/dist/HierarchicalCheckboxMenu.css +30 -0
  55. package/dist/HierarchicalCheckboxMenu.css.map +1 -0
  56. package/dist/HierarchicalCheckboxMenu.js +218 -0
  57. package/dist/HierarchicalCheckboxMenu.js.map +1 -0
  58. package/dist/ItemList.css +13 -0
  59. package/dist/ItemList.css.map +1 -0
  60. package/dist/ItemList.js +686 -0
  61. package/dist/ItemList.js.map +1 -0
  62. package/dist/ItemListItem.css +48 -0
  63. package/dist/ItemListItem.css.map +1 -0
  64. package/dist/ItemListItem.js +214 -0
  65. package/dist/ItemListItem.js.map +1 -0
  66. package/dist/LoadingOverlay.css +24 -0
  67. package/dist/LoadingOverlay.css.map +1 -0
  68. package/dist/LoadingOverlay.js +48 -0
  69. package/dist/LoadingOverlay.js.map +1 -0
  70. package/dist/LoadingSpinner.css +8 -0
  71. package/dist/LoadingSpinner.css.map +1 -0
  72. package/dist/LoadingSpinner.js +24 -0
  73. package/dist/LoadingSpinner.js.map +1 -0
  74. package/dist/MaskedInput.css +7 -0
  75. package/dist/MaskedInput.css.map +1 -0
  76. package/dist/MaskedInput.js +394 -0
  77. package/dist/MaskedInput.js.map +1 -0
  78. package/dist/MaskedInputUtils.js +36 -0
  79. package/dist/MaskedInputUtils.js.map +1 -0
  80. package/dist/Option.js +16 -0
  81. package/dist/Option.js.map +1 -0
  82. package/dist/RadioGroup.js +34 -0
  83. package/dist/RadioGroup.js.map +1 -0
  84. package/dist/RadioItem.js +55 -0
  85. package/dist/RadioItem.js.map +1 -0
  86. package/dist/RandomAreaPlotAnimation.css +18 -0
  87. package/dist/RandomAreaPlotAnimation.css.map +1 -0
  88. package/dist/RandomAreaPlotAnimation.js +290 -0
  89. package/dist/RandomAreaPlotAnimation.js.map +1 -0
  90. package/dist/SearchInput.css +43 -0
  91. package/dist/SearchInput.css.map +1 -0
  92. package/dist/SearchInput.js +66 -0
  93. package/dist/SearchInput.js.map +1 -0
  94. package/dist/Select.js +30 -0
  95. package/dist/Select.js.map +1 -0
  96. package/dist/SelectValueList.css +38 -0
  97. package/dist/SelectValueList.css.map +1 -0
  98. package/dist/SelectValueList.js +175 -0
  99. package/dist/SelectValueList.js.map +1 -0
  100. package/dist/SocketedButton.css +123 -0
  101. package/dist/SocketedButton.css.map +1 -0
  102. package/dist/SocketedButton.js +63 -0
  103. package/dist/SocketedButton.js.map +1 -0
  104. package/dist/SpectrumThemeDark.module.css +9 -0
  105. package/dist/SpectrumThemeDark.module.css.map +1 -0
  106. package/dist/SpectrumThemeLight.module.css +9 -0
  107. package/dist/SpectrumThemeLight.module.css.map +1 -0
  108. package/dist/SpectrumUtils.js +59 -0
  109. package/dist/SpectrumUtils.js.map +1 -0
  110. package/dist/ThemeExport.js +15 -0
  111. package/dist/ThemeExport.js.map +1 -0
  112. package/dist/ThemeExport.module.css +40 -0
  113. package/dist/ThemeExport.module.css.map +1 -0
  114. package/dist/TimeInput.js +101 -0
  115. package/dist/TimeInput.js.map +1 -0
  116. package/dist/TimeSlider.css +178 -0
  117. package/dist/TimeSlider.css.map +1 -0
  118. package/dist/TimeSlider.js +314 -0
  119. package/dist/TimeSlider.js.map +1 -0
  120. package/dist/TimeSlider.module.css +185 -0
  121. package/dist/TimeSlider.module.css.map +1 -0
  122. package/dist/ToastNotification.css +62 -0
  123. package/dist/ToastNotification.css.map +1 -0
  124. package/dist/ToastNotification.js +56 -0
  125. package/dist/ToastNotification.js.map +1 -0
  126. package/dist/UISwitch.css +94 -0
  127. package/dist/UISwitch.css.map +1 -0
  128. package/dist/UISwitch.js +30 -0
  129. package/dist/UISwitch.js.map +1 -0
  130. package/dist/ValidateLabelInput.css +9 -0
  131. package/dist/ValidateLabelInput.css.map +1 -0
  132. package/dist/ValidateLabelInput.js +50 -0
  133. package/dist/ValidateLabelInput.js.map +1 -0
  134. package/dist/context-actions/ContextActionUtils.js +142 -0
  135. package/dist/context-actions/ContextActionUtils.js.map +1 -0
  136. package/dist/context-actions/ContextActions.css +157 -0
  137. package/dist/context-actions/ContextActions.css.map +1 -0
  138. package/dist/context-actions/ContextActions.js +182 -0
  139. package/dist/context-actions/ContextActions.js.map +1 -0
  140. package/dist/context-actions/ContextMenu.js +559 -0
  141. package/dist/context-actions/ContextMenu.js.map +1 -0
  142. package/dist/context-actions/ContextMenuItem.js +139 -0
  143. package/dist/context-actions/ContextMenuItem.js.map +1 -0
  144. package/dist/context-actions/ContextMenuRoot.js +135 -0
  145. package/dist/context-actions/ContextMenuRoot.js.map +1 -0
  146. package/dist/context-actions/GlobalContextAction.js +53 -0
  147. package/dist/context-actions/GlobalContextAction.js.map +1 -0
  148. package/dist/context-actions/GlobalContextActions.js +28 -0
  149. package/dist/context-actions/GlobalContextActions.js.map +1 -0
  150. package/dist/context-actions/index.js +5 -0
  151. package/dist/context-actions/index.js.map +1 -0
  152. package/dist/declaration.d.js +2 -0
  153. package/dist/declaration.d.js.map +1 -0
  154. package/dist/index.js +52 -0
  155. package/dist/index.js.map +1 -0
  156. package/dist/menu-actions/DropdownMenu.css +39 -0
  157. package/dist/menu-actions/DropdownMenu.css.map +1 -0
  158. package/dist/menu-actions/DropdownMenu.js +174 -0
  159. package/dist/menu-actions/DropdownMenu.js.map +1 -0
  160. package/dist/menu-actions/Menu.js +244 -0
  161. package/dist/menu-actions/Menu.js.map +1 -0
  162. package/dist/menu-actions/index.js +4 -0
  163. package/dist/menu-actions/index.js.map +1 -0
  164. package/dist/modal/DebouncedModal.js +26 -0
  165. package/dist/modal/DebouncedModal.js.map +1 -0
  166. package/dist/modal/InfoModal.css +24 -0
  167. package/dist/modal/InfoModal.css.map +1 -0
  168. package/dist/modal/InfoModal.js +34 -0
  169. package/dist/modal/InfoModal.js.map +1 -0
  170. package/dist/modal/Modal.js +122 -0
  171. package/dist/modal/Modal.js.map +1 -0
  172. package/dist/modal/ModalBody.js +16 -0
  173. package/dist/modal/ModalBody.js.map +1 -0
  174. package/dist/modal/ModalFooter.js +14 -0
  175. package/dist/modal/ModalFooter.js.map +1 -0
  176. package/dist/modal/ModalHeader.js +27 -0
  177. package/dist/modal/ModalHeader.js.map +1 -0
  178. package/dist/modal/index.js +7 -0
  179. package/dist/modal/index.js.map +1 -0
  180. package/dist/navigation/Menu.css +13 -0
  181. package/dist/navigation/Menu.css.map +1 -0
  182. package/dist/navigation/Menu.js +25 -0
  183. package/dist/navigation/Menu.js.map +1 -0
  184. package/dist/navigation/MenuItem.css +46 -0
  185. package/dist/navigation/MenuItem.css.map +1 -0
  186. package/dist/navigation/MenuItem.js +65 -0
  187. package/dist/navigation/MenuItem.js.map +1 -0
  188. package/dist/navigation/Page.css +34 -0
  189. package/dist/navigation/Page.css.map +1 -0
  190. package/dist/navigation/Page.js +46 -0
  191. package/dist/navigation/Page.js.map +1 -0
  192. package/dist/navigation/Stack.css +24 -0
  193. package/dist/navigation/Stack.css.map +1 -0
  194. package/dist/navigation/Stack.js +82 -0
  195. package/dist/navigation/Stack.js.map +1 -0
  196. package/dist/navigation/index.js +5 -0
  197. package/dist/navigation/index.js.map +1 -0
  198. package/dist/popper/Popper.css +127 -0
  199. package/dist/popper/Popper.css.map +1 -0
  200. package/dist/popper/Popper.js +283 -0
  201. package/dist/popper/Popper.js.map +1 -0
  202. package/dist/popper/Tooltip.js +283 -0
  203. package/dist/popper/Tooltip.js.map +1 -0
  204. package/dist/popper/index.js +3 -0
  205. package/dist/popper/index.js.map +1 -0
  206. package/dist/shortcuts/GlobalShortcuts.js +47 -0
  207. package/dist/shortcuts/GlobalShortcuts.js.map +1 -0
  208. package/dist/shortcuts/Shortcut.js +393 -0
  209. package/dist/shortcuts/Shortcut.js.map +1 -0
  210. package/dist/shortcuts/ShortcutRegistry.js +78 -0
  211. package/dist/shortcuts/ShortcutRegistry.js.map +1 -0
  212. package/dist/shortcuts/index.js +5 -0
  213. package/dist/shortcuts/index.js.map +1 -0
  214. package/package.json +7 -7
@@ -0,0 +1,686 @@
1
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
4
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
5
+ /* eslint-disable react/no-unstable-nested-components */
6
+ import React, { PureComponent } from 'react';
7
+ import memoize from 'memoizee';
8
+ import { FixedSizeList as List } from 'react-window';
9
+ import AutoSizer from 'react-virtualized-auto-sizer';
10
+ import Log from '@deephaven/log';
11
+ import { RangeUtils } from '@deephaven/utils';
12
+ import ItemListItem from "./ItemListItem.js";
13
+ import { ContextActionUtils } from "./context-actions/index.js";
14
+ import "./ItemList.css";
15
+ var log = Log.module('ItemList');
16
+ var MIN_DRAG_DELTA = 5;
17
+ /**
18
+ * Show items in a long scrollable list.
19
+ * Can be navigated via keyboard or mouse.
20
+ */
21
+ export class ItemList extends PureComponent {
22
+ // By drawing an additional 10 items on each side, tab/keyboard navigation works better (as the next element exists)
23
+
24
+ static renderItem(_ref) {
25
+ var _ref2, _item$displayValue;
26
+ var {
27
+ item
28
+ } = _ref;
29
+ return /*#__PURE__*/React.createElement("div", {
30
+ className: "item-list-item-content"
31
+ }, item != null && ((_ref2 = (_item$displayValue = item.displayValue) !== null && _item$displayValue !== void 0 ? _item$displayValue : item.value) !== null && _ref2 !== void 0 ? _ref2 : "".concat(item)));
32
+ }
33
+ constructor(_props) {
34
+ super(_props);
35
+ _defineProperty(this, "list", void 0);
36
+ _defineProperty(this, "listContainer", void 0);
37
+ _defineProperty(this, "getItemSelected", memoize((index, selectedRanges) => RangeUtils.isSelected(selectedRanges, index), {
38
+ max: ItemList.CACHE_SIZE
39
+ }));
40
+ _defineProperty(this, "getCachedItem", memoize((itemIndex, key, item, isFocused, isSelected, renderItem, style, disableSelect) => {
41
+ var content = renderItem({
42
+ item,
43
+ itemIndex,
44
+ isFocused,
45
+ isSelected,
46
+ style
47
+ });
48
+ return /*#__PURE__*/React.createElement(ItemListItem, {
49
+ onContextMenu: this.handleItemContextMenu,
50
+ onDoubleClick: this.handleItemDoubleClick,
51
+ onMouseDown: this.handleItemMouseDown,
52
+ onFocus: this.handleItemFocus,
53
+ onBlur: this.handleItemBlur,
54
+ disableSelect: disableSelect,
55
+ onMouseMove: this.handleItemMouseMove,
56
+ onMouseUp: this.handleItemMouseUp,
57
+ isFocused: isFocused,
58
+ isSelected: isSelected,
59
+ itemIndex: itemIndex,
60
+ style: style,
61
+ key: key
62
+ }, content);
63
+ }, {
64
+ max: ItemList.CACHE_SIZE
65
+ }));
66
+ _defineProperty(this, "getOuterElement", memoize(onKeyDown => {
67
+ var component = /*#__PURE__*/React.forwardRef((props, ref) =>
68
+ /*#__PURE__*/
69
+ // We need to add the tabIndex to make sure it is focusable, otherwise we can't get key events
70
+ React.createElement("div", _extends({
71
+ ref: ref,
72
+ tabIndex: -1,
73
+ onKeyDown: onKeyDown,
74
+ role: "presentation"
75
+ // eslint-disable-next-line react/jsx-props-no-spreading
76
+ }, props)));
77
+ component.displayName = 'ItemListOuterElement';
78
+ return component;
79
+ }));
80
+ _defineProperty(this, "getInnerElement", memoize(() => {
81
+ var component = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React.createElement("div", _extends({
82
+ className: "item-list-inner-element",
83
+ ref: ref
84
+ // eslint-disable-next-line react/jsx-props-no-spreading
85
+ }, props)));
86
+ component.displayName = 'ItemListInnerElement';
87
+ return component;
88
+ }));
89
+ _defineProperty(this, "getItemData", memoize((items, selectedRanges, renderItem) => ({
90
+ items,
91
+ selectedRanges,
92
+ renderItem
93
+ })));
94
+ this.handleItemBlur = this.handleItemBlur.bind(this);
95
+ this.handleItemContextMenu = this.handleItemContextMenu.bind(this);
96
+ this.handleItemFocus = this.handleItemFocus.bind(this);
97
+ this.handleItemDoubleClick = this.handleItemDoubleClick.bind(this);
98
+ this.handleItemMouseDown = this.handleItemMouseDown.bind(this);
99
+ this.handleItemMouseMove = this.handleItemMouseMove.bind(this);
100
+ this.handleItemMouseUp = this.handleItemMouseUp.bind(this);
101
+ this.handleItemsRendered = this.handleItemsRendered.bind(this);
102
+ this.handleWindowMouseUp = this.handleWindowMouseUp.bind(this);
103
+ this.handleKeyDown = this.handleKeyDown.bind(this);
104
+ this.handleMouseLeave = this.handleMouseLeave.bind(this);
105
+ this.handleScroll = this.handleScroll.bind(this);
106
+ this.handleResize = this.handleResize.bind(this);
107
+ this.renderInnerElement = this.renderInnerElement.bind(this);
108
+ this.list = /*#__PURE__*/React.createRef();
109
+ this.listContainer = /*#__PURE__*/React.createRef();
110
+ var {
111
+ isStickyBottom,
112
+ selectedRanges: _selectedRanges
113
+ } = _props;
114
+ this.state = {
115
+ focusIndex: null,
116
+ mouseDownIndex: null,
117
+ selectedRanges: _selectedRanges,
118
+ overscanStartIndex: 0,
119
+ height: null,
120
+ isDragging: false,
121
+ isStuckToBottom: isStickyBottom,
122
+ scrollOffset: null,
123
+ mouseX: null,
124
+ mouseY: null
125
+ };
126
+ }
127
+ componentDidUpdate(prevProps, prevState) {
128
+ var {
129
+ selectedRanges: propSelectedRanges,
130
+ itemCount
131
+ } = this.props;
132
+ var {
133
+ focusIndex,
134
+ isStuckToBottom,
135
+ scrollOffset,
136
+ height,
137
+ selectedRanges
138
+ } = this.state;
139
+ if (isStuckToBottom && !this.isListAtBottom() && itemCount > 0) {
140
+ this.scrollToBottom();
141
+ }
142
+ if (scrollOffset !== prevState.scrollOffset || height !== prevState.height) {
143
+ this.sendViewportUpdate();
144
+ }
145
+ if (propSelectedRanges !== prevProps.selectedRanges && propSelectedRanges !== selectedRanges) {
146
+ this.setSelectedRanges(propSelectedRanges);
147
+ } else if (selectedRanges !== prevState.selectedRanges) {
148
+ var {
149
+ onSelectionChange: _onSelectionChange
150
+ } = this.props;
151
+ _onSelectionChange(selectedRanges);
152
+ }
153
+ if (focusIndex !== prevState.focusIndex) {
154
+ var {
155
+ onFocusChange: _onFocusChange
156
+ } = this.props;
157
+ _onFocusChange(focusIndex);
158
+ }
159
+ }
160
+ componentWillUnmount() {
161
+ window.removeEventListener('mouseup', this.handleWindowMouseUp);
162
+ }
163
+ focus() {
164
+ var _this$listContainer$c;
165
+ (_this$listContainer$c = this.listContainer.current) === null || _this$listContainer$c === void 0 ? void 0 : _this$listContainer$c.focus();
166
+ }
167
+ restoreScrollPosition() {
168
+ var {
169
+ scrollOffset
170
+ } = this.state;
171
+ if (scrollOffset != null) {
172
+ var _this$listContainer$c2;
173
+ // manually restore the scroll containers offset
174
+ // virtual list doesn't restore scrolloffset in a re-render if it's the same
175
+ (_this$listContainer$c2 = this.listContainer.current) === null || _this$listContainer$c2 === void 0 ? void 0 : _this$listContainer$c2.scrollTo(0, scrollOffset);
176
+ }
177
+ }
178
+ getElement(itemIndex) {
179
+ if (this.listContainer.current == null) {
180
+ return null;
181
+ }
182
+ var {
183
+ focusSelector
184
+ } = this.props;
185
+ var {
186
+ overscanStartIndex
187
+ } = this.state;
188
+ var elements = this.listContainer.current.querySelectorAll(focusSelector);
189
+ var elementIndex = itemIndex - overscanStartIndex;
190
+ return elements[elementIndex];
191
+ }
192
+ focusItem(itemIndex) {
193
+ var {
194
+ disableSelect
195
+ } = this.props;
196
+ if (disableSelect) return;
197
+ this.setState({
198
+ focusIndex: itemIndex
199
+ });
200
+ var element = this.getElement(itemIndex);
201
+ if (element instanceof HTMLElement) {
202
+ element.focus();
203
+ }
204
+ }
205
+ scrollToItem(itemIndex) {
206
+ var element = this.getElement(itemIndex);
207
+ if (element != null) {
208
+ element.scrollIntoView({
209
+ block: 'center'
210
+ });
211
+ }
212
+ }
213
+ handleItemContextMenu(itemIndex, e) {
214
+ // Update the selection, but don't consume the mouse event - it will trigger the context menu
215
+ var {
216
+ selectedRanges
217
+ } = this.state;
218
+ var isSelected = RangeUtils.isSelected(selectedRanges, itemIndex);
219
+
220
+ // When right-clicking, we want to maintain the current selection if the right click happened within the selection even if the modifier key isn't down
221
+ var isModifierDown = isSelected || ContextActionUtils.isModifierKeyDown(e);
222
+ this.toggleSelect(itemIndex, e.shiftKey, isModifierDown, false);
223
+ }
224
+ handleItemDoubleClick(itemIndex, e) {
225
+ var {
226
+ isDoubleClickSelect,
227
+ onSelect
228
+ } = this.props;
229
+ if (isDoubleClickSelect) {
230
+ this.setState(_ref3 => {
231
+ var {
232
+ selectedRanges
233
+ } = _ref3;
234
+ return {
235
+ selectedRanges: RangeUtils.selectRange(selectedRanges, [itemIndex, itemIndex])
236
+ };
237
+ }, () => {
238
+ onSelect(itemIndex, e);
239
+ });
240
+ }
241
+ }
242
+ handleItemMouseDown(index, e) {
243
+ var {
244
+ selectedRanges
245
+ } = this.state;
246
+ if (e.target instanceof HTMLElement && ['button', 'select', 'input', 'textarea'].indexOf(e.target.tagName.toLowerCase()) !== -1) {
247
+ // allow these elements to do their own behaviours
248
+ return;
249
+ }
250
+ if (e.button === 2 && selectedRanges.length === 0) {
251
+ // allow right click to act as a selection if selection is empty
252
+ this.focusItem(index);
253
+ this.selectItem(index);
254
+ return;
255
+ }
256
+ if (e.button != null && e.button !== 0) {
257
+ return;
258
+ }
259
+ this.setState({
260
+ mouseDownIndex: index,
261
+ mouseX: e.clientX,
262
+ mouseY: e.clientY
263
+ });
264
+ window.addEventListener('mouseup', this.handleWindowMouseUp);
265
+
266
+ // Leave selection until mouse up, to allow for dragging behaviour
267
+ }
268
+
269
+ handleItemBlur(itemIndex, e) {
270
+ log.debug2('item blur', itemIndex, e.currentTarget, e.relatedTarget);
271
+ if (!e.relatedTarget || this.listContainer.current && e.relatedTarget instanceof HTMLElement && !this.listContainer.current.contains(e.relatedTarget)) {
272
+ // Next focused element is outside of the ItemList
273
+ this.setState({
274
+ focusIndex: null
275
+ });
276
+ }
277
+ }
278
+ handleItemFocus(itemIndex, e) {
279
+ log.debug2('item focus', itemIndex, e.target);
280
+ this.setState(state => {
281
+ var {
282
+ focusIndex
283
+ } = state;
284
+ if (focusIndex !== itemIndex) {
285
+ return {
286
+ focusIndex: itemIndex
287
+ };
288
+ }
289
+ return null;
290
+ });
291
+ }
292
+ handleItemMouseMove(itemIndex, e) {
293
+ var {
294
+ isDragSelect,
295
+ isMultiSelect,
296
+ disableSelect
297
+ } = this.props;
298
+ var {
299
+ mouseDownIndex,
300
+ selectedRanges,
301
+ mouseX,
302
+ mouseY
303
+ } = this.state;
304
+ if (mouseDownIndex == null || disableSelect) return;
305
+ var mouseMoveX = Math.abs(e.clientX - (mouseX !== null && mouseX !== void 0 ? mouseX : 0));
306
+ var mouseMoveY = Math.abs(e.clientY - (mouseY !== null && mouseY !== void 0 ? mouseY : 0));
307
+ if (mouseMoveX > MIN_DRAG_DELTA && mouseMoveY > MIN_DRAG_DELTA) {
308
+ this.setState({
309
+ isDragging: true
310
+ });
311
+ }
312
+ if (isDragSelect || mouseDownIndex === itemIndex) {
313
+ this.focusItem(itemIndex);
314
+ if (isMultiSelect) {
315
+ if (!isDragSelect && !this.getItemSelected(itemIndex, selectedRanges) && !ContextActionUtils.isModifierKeyDown(e)) {
316
+ // If there's already a selection and they select outside of that range while dragging without a modifier key, start a new selection with just the new item
317
+ this.deselectAll();
318
+ }
319
+ this.selectRange([Math.min(mouseDownIndex, itemIndex), Math.max(mouseDownIndex, itemIndex)]);
320
+ } else {
321
+ this.toggleSelect(itemIndex, e.shiftKey, ContextActionUtils.isModifierKeyDown(e), false);
322
+ }
323
+ }
324
+ }
325
+ handleItemMouseUp(index, e) {
326
+ var {
327
+ isDeselectOnClick,
328
+ isDoubleClickSelect,
329
+ onSelect
330
+ } = this.props;
331
+ var {
332
+ mouseDownIndex,
333
+ isDragging
334
+ } = this.state;
335
+ if (e.target instanceof HTMLElement && ['button', 'select', 'input', 'textarea'].indexOf(e.target.tagName.toLowerCase()) !== -1) {
336
+ return;
337
+ }
338
+ if (mouseDownIndex === index && !isDragging) {
339
+ var isShiftDown = e.shiftKey;
340
+ var isModifierDown = ContextActionUtils.isModifierKeyDown(e);
341
+ this.focusItem(index);
342
+ this.toggleSelect(index, isShiftDown, isModifierDown, isDeselectOnClick);
343
+ if (!isDoubleClickSelect && !isShiftDown && !isModifierDown) {
344
+ onSelect(index, e);
345
+ }
346
+ }
347
+ this.resetMouseState();
348
+ }
349
+ handleItemsRendered(_ref4) {
350
+ var {
351
+ overscanStartIndex
352
+ } = _ref4;
353
+ this.setState({
354
+ overscanStartIndex
355
+ });
356
+ }
357
+ handleResize(_ref5) {
358
+ var {
359
+ height
360
+ } = _ref5;
361
+ this.setState({
362
+ height
363
+ });
364
+ }
365
+ handleMouseLeave() {
366
+ this.setState({
367
+ mouseDownIndex: null
368
+ });
369
+ }
370
+ handleWindowMouseUp() {
371
+ this.resetMouseState();
372
+ window.removeEventListener('mouseup', this.handleWindowMouseUp);
373
+ }
374
+ handleKeyDown(e) {
375
+ var {
376
+ isMultiSelect,
377
+ itemCount,
378
+ onSelect
379
+ } = this.props;
380
+ var {
381
+ focusIndex: oldFocus
382
+ } = this.state;
383
+ var newFocus = oldFocus;
384
+ if (e.key === 'Enter' || e.key === ' ') {
385
+ if (!isMultiSelect && newFocus != null) {
386
+ this.setState({
387
+ selectedRanges: [[newFocus, newFocus]]
388
+ }, () => {
389
+ if (newFocus != null) {
390
+ onSelect(newFocus, e);
391
+ }
392
+ });
393
+ }
394
+ return;
395
+ }
396
+ if (e.key === 'ArrowUp') {
397
+ if (newFocus != null && newFocus >= 0) {
398
+ newFocus = Math.max(0, newFocus - 1);
399
+ } else {
400
+ newFocus = itemCount - 1;
401
+ }
402
+ } else if (e.key === 'ArrowDown') {
403
+ if (newFocus != null && newFocus >= 0) {
404
+ newFocus = Math.min(newFocus + 1, itemCount - 1);
405
+ } else {
406
+ newFocus = 0;
407
+ }
408
+ } else {
409
+ return;
410
+ }
411
+ if (oldFocus !== newFocus) {
412
+ e.stopPropagation();
413
+ e.preventDefault();
414
+ this.focusItem(newFocus);
415
+ var {
416
+ selectedRanges
417
+ } = this.state;
418
+ if (e.shiftKey && selectedRanges.length > 0) {
419
+ var lastRange = selectedRanges[selectedRanges.length - 1];
420
+ this.selectRange([Math.min(newFocus, lastRange[0]), Math.max(newFocus, lastRange[1])]);
421
+ } else {
422
+ this.deselectAll();
423
+ if (newFocus !== null) {
424
+ this.selectItem(newFocus);
425
+ } else {
426
+ var _this$listContainer$c3;
427
+ (_this$listContainer$c3 = this.listContainer.current) === null || _this$listContainer$c3 === void 0 ? void 0 : _this$listContainer$c3.focus();
428
+ }
429
+ }
430
+ this.scrollIntoView(newFocus);
431
+ }
432
+ }
433
+ handleScroll(_ref6) {
434
+ var {
435
+ scrollUpdateWasRequested,
436
+ scrollOffset
437
+ } = _ref6;
438
+ this.setState(state => {
439
+ if (scrollUpdateWasRequested) {
440
+ // The scroll was caused by scrollTo() or scrollToItem()
441
+ // Don't re-calc isStuckToBottom
442
+ return {
443
+ scrollOffset
444
+ };
445
+ }
446
+ var {
447
+ isStickyBottom
448
+ } = this.props;
449
+ var {
450
+ height
451
+ } = state;
452
+ var isStuckToBottom = isStickyBottom && this.isListAtBottom({
453
+ scrollOffset,
454
+ height
455
+ });
456
+ return {
457
+ isStuckToBottom,
458
+ scrollOffset
459
+ };
460
+ });
461
+ }
462
+ resetMouseState() {
463
+ this.setState({
464
+ mouseDownIndex: null,
465
+ isDragging: false
466
+ });
467
+ }
468
+ scrollToBottom() {
469
+ var {
470
+ itemCount
471
+ } = this.props;
472
+ if (this.list.current) {
473
+ this.list.current.scrollToItem(itemCount);
474
+ }
475
+ }
476
+ scrollIntoView(itemIndex) {
477
+ if (this.list.current) {
478
+ this.list.current.scrollToItem(itemIndex);
479
+ }
480
+ }
481
+
482
+ /**
483
+ * @param index The index to toggle selection for
484
+ * @param isShiftDown True if the shift modifier key is down
485
+ * @param isModifierDown True if the meta modifier key is down
486
+ * @param isDeselectable True if item should be deselected if already selected
487
+ */
488
+ toggleSelect(index, isShiftDown, isModifierDown) {
489
+ var isDeselectable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
490
+ var {
491
+ isMultiSelect
492
+ } = this.props;
493
+ var {
494
+ selectedRanges
495
+ } = this.state;
496
+ if (isMultiSelect && isShiftDown && selectedRanges.length > 0) {
497
+ var lastRange = selectedRanges[selectedRanges.length - 1];
498
+ this.selectRange([Math.min(lastRange[0], index), Math.max(index, lastRange[1])]);
499
+ } else if (isMultiSelect && selectedRanges.length === 1 && selectedRanges[0][0] === index && selectedRanges[0][1] === index) {
500
+ if (isDeselectable) {
501
+ this.deselectItem(index);
502
+ }
503
+ } else if (isMultiSelect && isModifierDown) {
504
+ if (this.getItemSelected(index, selectedRanges)) {
505
+ if (isDeselectable) {
506
+ this.deselectItem(index);
507
+ }
508
+ } else {
509
+ this.selectItem(index);
510
+ }
511
+ } else {
512
+ this.deselectAll();
513
+ this.selectItem(index);
514
+ }
515
+ }
516
+ deselectAll() {
517
+ var {
518
+ itemCount
519
+ } = this.props;
520
+ this.deselectRange([0, itemCount]);
521
+ }
522
+ deselectItem(index) {
523
+ this.deselectRange([index, index]);
524
+ }
525
+ deselectRange(range) {
526
+ RangeUtils.validateRange(range);
527
+ this.setState(_ref7 => {
528
+ var {
529
+ selectedRanges
530
+ } = _ref7;
531
+ return {
532
+ selectedRanges: RangeUtils.deselectRange(selectedRanges, range)
533
+ };
534
+ });
535
+ }
536
+ selectItem(index) {
537
+ var {
538
+ disableSelect
539
+ } = this.props;
540
+ if (disableSelect) return;
541
+ this.selectRange([index, index]);
542
+ }
543
+ selectRange(range) {
544
+ RangeUtils.validateRange(range);
545
+ this.setState(_ref8 => {
546
+ var {
547
+ selectedRanges
548
+ } = _ref8;
549
+ return {
550
+ selectedRanges: RangeUtils.selectRange(selectedRanges, range)
551
+ };
552
+ });
553
+ }
554
+ setSelectedRanges(selectedRanges) {
555
+ this.setState({
556
+ selectedRanges
557
+ });
558
+ }
559
+ sendViewportUpdate() {
560
+ var {
561
+ scrollOffset,
562
+ height
563
+ } = this.state;
564
+ if (scrollOffset != null && height != null) {
565
+ var {
566
+ onViewportChange: _onViewportChange,
567
+ rowHeight
568
+ } = this.props;
569
+ var _topRow = Math.floor(scrollOffset / rowHeight);
570
+ var _bottomRow = _topRow + Math.ceil(height / rowHeight);
571
+ _onViewportChange(_topRow, _bottomRow);
572
+ }
573
+ }
574
+ isListAtBottom() {
575
+ var {
576
+ scrollOffset,
577
+ height
578
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
579
+ if (height == null || scrollOffset == null) {
580
+ return false;
581
+ }
582
+ var {
583
+ itemCount,
584
+ rowHeight
585
+ } = this.props;
586
+ return scrollOffset + height >= itemCount * rowHeight;
587
+ }
588
+ renderInnerElement(_ref9) {
589
+ var {
590
+ index: itemIndex,
591
+ style
592
+ } = _ref9;
593
+ var {
594
+ items,
595
+ offset,
596
+ renderItem,
597
+ disableSelect
598
+ } = this.props;
599
+ var {
600
+ focusIndex,
601
+ selectedRanges
602
+ } = this.state;
603
+ if (itemIndex < offset || itemIndex >= offset + items.length) {
604
+ return null;
605
+ }
606
+ var item = items[itemIndex - offset];
607
+ return this.getCachedItem(itemIndex, itemIndex, item, itemIndex === focusIndex && !disableSelect, this.getItemSelected(itemIndex, selectedRanges), renderItem, style, disableSelect);
608
+ }
609
+ render() {
610
+ var {
611
+ items,
612
+ itemCount,
613
+ overscanCount,
614
+ renderItem,
615
+ rowHeight,
616
+ 'data-testid': dataTestId
617
+ } = this.props;
618
+ var {
619
+ selectedRanges,
620
+ isStuckToBottom
621
+ } = this.state;
622
+ return /*#__PURE__*/React.createElement(AutoSizer, {
623
+ className: "item-list-auto-sizer",
624
+ onResize: this.handleResize
625
+ }, _ref10 => {
626
+ var {
627
+ width,
628
+ height
629
+ } = _ref10;
630
+ return /*#__PURE__*/React.createElement(List, {
631
+ className: "item-list-scroll-pane",
632
+ height: height,
633
+ width: width,
634
+ initialScrollOffset: isStuckToBottom ? itemCount * rowHeight : 0,
635
+ itemCount: itemCount,
636
+ itemSize: rowHeight
637
+ // This prop isn't actually used by us, it is passed to the render function by react-window
638
+ // Used here to force a re-render of the List component.
639
+ // Otherwise it doesn't know to call the render again when selection or renderItem changes
640
+ ,
641
+ itemData: this.getItemData(items, selectedRanges, renderItem),
642
+ onScroll: this.handleScroll,
643
+ onItemsRendered: this.handleItemsRendered,
644
+ ref: this.list,
645
+ outerElementType: this.getOuterElement(this.handleKeyDown),
646
+ outerRef: this.listContainer,
647
+ innerElementType: this.getInnerElement(),
648
+ overscanCount: overscanCount,
649
+ "data-testid": dataTestId
650
+ }, this.renderInnerElement);
651
+ });
652
+ }
653
+ }
654
+ _defineProperty(ItemList, "CACHE_SIZE", 1000);
655
+ _defineProperty(ItemList, "DEFAULT_ROW_HEIGHT", 20);
656
+ _defineProperty(ItemList, "DEFAULT_OVERSCAN", 10);
657
+ _defineProperty(ItemList, "defaultProps", {
658
+ offset: 0,
659
+ items: [],
660
+ rowHeight: ItemList.DEFAULT_ROW_HEIGHT,
661
+ isDeselectOnClick: true,
662
+ isDoubleClickSelect: false,
663
+ isDragSelect: true,
664
+ isMultiSelect: false,
665
+ isStickyBottom: false,
666
+ disableSelect: false,
667
+ onFocusChange() {
668
+ // no-op
669
+ },
670
+ onSelect() {
671
+ // no-op
672
+ },
673
+ onSelectionChange() {
674
+ // no-op
675
+ },
676
+ onViewportChange() {
677
+ // no-op
678
+ },
679
+ overscanCount: ItemList.DEFAULT_OVERSCAN,
680
+ renderItem: ItemList.renderItem,
681
+ selectedRanges: [],
682
+ focusSelector: '.item-list-item',
683
+ 'data-testid': undefined
684
+ });
685
+ export default ItemList;
686
+ //# sourceMappingURL=ItemList.js.map