@defra/interactive-map 0.0.22-alpha → 0.0.23-alpha
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/css/index.css +1 -1
- package/dist/esm/im-core.js +1 -1
- package/dist/esm/im-shell.js +1 -1
- package/dist/umd/im-core.js +1 -1
- package/dist/umd/index.js +1 -1
- package/docs/api/button-definition.md +39 -0
- package/docs/api/context.md +4 -4
- package/docs/api/map-style-config.md +11 -2
- package/docs/api/marker-config.md +38 -7
- package/docs/api/panel-definition.md +7 -3
- package/docs/api/symbol-config.md +10 -26
- package/docs/api/symbol-registry.md +28 -13
- package/docs/api.md +24 -2
- package/docs/assets/css/{docusaurus.css → docusaurus.scss} +18 -12
- package/docs/assets/images/toggle-marker-label.jpg +0 -0
- package/docs/examples/index.mdx +12 -0
- package/docs/examples/toggle-marker-label.mdx +89 -0
- package/docs/plugins/interact.md +4 -11
- package/docusaurus.config.cjs +2 -1
- package/package.json +8 -8
- package/plugins/beta/datasets/dist/adapters/maplibre/esm/im-datasets-ml-adapter.js +1 -1
- package/plugins/beta/datasets/dist/css/index.css +2 -2
- package/plugins/beta/datasets/dist/esm/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/umd/maplibre/im-datasets-maplibre-adapter.js +1 -1
- package/plugins/beta/datasets/dist/umd/maplibre/im-datasets-plugin.js +1 -1
- package/plugins/beta/datasets/dist/umd/maplibre/index.js +1 -1
- package/plugins/beta/datasets/src/adapters/maplibre/layerBuilders.js +5 -5
- package/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js +24 -29
- package/plugins/beta/datasets/src/adapters/maplibre/patternImages.js +2 -2
- package/plugins/beta/datasets/src/adapters/maplibre/symbolImages.js +3 -3
- package/plugins/beta/datasets/src/components/KeySvg.jsx +2 -2
- package/plugins/beta/datasets/src/components/KeySvgPattern.jsx +1 -2
- package/plugins/beta/datasets/src/components/svgProperties.js +2 -2
- package/plugins/beta/datasets/src/panels/Key.module.scss +2 -2
- package/plugins/beta/draw-es/dist/esm/im-draw-es-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/esm/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/draw-ml/dist/umd/im-draw-ml-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/esm/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/im-map-styles-plugin.js +1 -1
- package/plugins/beta/map-styles/dist/umd/index.js +1 -1
- package/plugins/beta/use-location/dist/esm/im-use-location-plugin.js +1 -1
- package/plugins/beta/use-location/dist/umd/im-use-location-plugin.js +1 -1
- package/plugins/beta/use-location/src/manifest.js +1 -0
- package/plugins/interact/dist/esm/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/im-interact-plugin.js +1 -1
- package/plugins/interact/dist/umd/index.js +1 -1
- package/plugins/interact/src/InteractInit.jsx +23 -55
- package/plugins/interact/src/InteractInit.test.js +58 -80
- package/plugins/interact/src/defaults.js +1 -3
- package/plugins/interact/src/hooks/useAttachEvents.js +46 -0
- package/plugins/interact/src/hooks/useAttachEvents.test.js +65 -0
- package/plugins/interact/src/hooks/useCrossHairVisibility.js +47 -0
- package/plugins/interact/src/hooks/useCrossHairVisibility.test.js +54 -0
- package/plugins/interact/src/hooks/useHighlightSync.js +30 -8
- package/plugins/interact/src/hooks/useHighlightSync.test.js +127 -80
- package/plugins/interact/src/hooks/useInteractionHandlers.js +18 -17
- package/plugins/interact/src/hooks/useInteractionHandlers.test.js +22 -61
- package/plugins/interact/src/hooks/useMapItemList.js +187 -0
- package/plugins/interact/src/hooks/useMapItemList.test.js +584 -0
- package/plugins/interact/src/index.js +0 -2
- package/plugins/interact/src/index.test.js +0 -2
- package/plugins/interact/src/manifest.js +37 -6
- package/plugins/interact/src/reducer.js +8 -4
- package/plugins/interact/src/reducer.test.js +18 -3
- package/plugins/interact/src/utils/buildStylesMap.js +21 -10
- package/plugins/interact/src/utils/buildStylesMap.test.js +29 -29
- package/plugins/interact/src/utils/spatial.js +0 -15
- package/plugins/interact/src/utils/spatial.test.js +1 -13
- package/plugins/search/dist/css/index.css +1 -1
- package/plugins/search/dist/esm/im-search-plugin.js +1 -1
- package/plugins/search/dist/umd/im-search-plugin.js +1 -1
- package/plugins/search/src/components/CloseButton/CloseButton.module.scss +2 -0
- package/plugins/search/src/components/OpenButton/OpenButton.jsx +1 -1
- package/plugins/search/src/components/OpenButton/OpenButton.module.scss +3 -0
- package/plugins/search/src/search.scss +1 -0
- package/providers/beta/esri/dist/esm/im-esri-provider.js +1 -1
- package/providers/beta/esri/src/esriProvider.js +4 -0
- package/providers/maplibre/dist/esm/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/esm/index.js +1 -1
- package/providers/maplibre/dist/umd/im-maplibre-provider.js +1 -1
- package/providers/maplibre/dist/umd/index.js +1 -1
- package/providers/maplibre/src/index.js +1 -1
- package/providers/maplibre/src/index.test.js +9 -14
- package/providers/maplibre/src/mapEvents.js +11 -5
- package/providers/maplibre/src/mapEvents.test.js +14 -3
- package/providers/maplibre/src/maplibreProvider.js +18 -11
- package/providers/maplibre/src/maplibreProvider.test.js +43 -36
- package/providers/maplibre/src/utils/highlightFeatures.js +102 -57
- package/providers/maplibre/src/utils/highlightFeatures.test.js +162 -51
- package/providers/maplibre/src/utils/maplibreFixes.js +10 -0
- package/providers/maplibre/src/utils/maplibreFixes.test.js +31 -0
- package/providers/maplibre/src/utils/patternImages.js +10 -12
- package/providers/maplibre/src/utils/patternImages.test.js +145 -167
- package/providers/maplibre/src/utils/rasteriseToImageData.js +1 -4
- package/providers/maplibre/src/utils/rasteriseToImageData.test.js +23 -24
- package/providers/maplibre/src/utils/symbolImages.js +23 -86
- package/providers/maplibre/src/utils/symbolImages.test.js +60 -105
- package/src/App/components/Actions/Actions.module.scss +1 -0
- package/src/App/components/Actions/Actions.test.jsx +17 -4
- package/src/App/components/Hints/Hints.jsx +52 -0
- package/src/App/components/Hints/Hints.module.scss +37 -0
- package/src/App/components/Hints/Hints.test.jsx +104 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.jsx +57 -19
- package/src/App/components/KeyboardHelp/KeyboardHelp.module.scss +10 -0
- package/src/App/components/KeyboardHelp/KeyboardHelp.test.jsx +140 -31
- package/src/App/components/Markers/LabelMarker.jsx +14 -0
- package/src/App/components/Markers/LabelMarker.test.jsx +36 -0
- package/src/App/components/Markers/Markers.jsx +44 -75
- package/src/App/components/Markers/Markers.module.scss +58 -0
- package/src/App/components/Markers/Markers.test.jsx +90 -113
- package/src/App/components/Markers/SymbolLabelMarker.jsx +43 -0
- package/src/App/components/Markers/SymbolLabelMarker.test.jsx +56 -0
- package/src/App/components/Markers/SymbolMarker.jsx +31 -0
- package/src/App/components/Markers/SymbolMarker.test.jsx +72 -0
- package/src/App/components/Panel/Panel.jsx +1 -1
- package/src/App/components/Panel/Panel.module.scss +1 -0
- package/src/App/components/PopupMenu/PopupMenu.test.jsx +117 -1
- package/src/App/components/PopupMenu/usePopupMenu.js +132 -85
- package/src/App/components/Tabs/Tabs.jsx +68 -0
- package/src/App/components/Tabs/Tabs.module.scss +57 -0
- package/src/App/components/Tabs/Tabs.test.jsx +121 -0
- package/src/App/components/Tooltip/Tooltip.module.scss +1 -1
- package/src/App/components/Viewport/Features.jsx +35 -0
- package/src/App/components/Viewport/Features.module.scss +31 -0
- package/src/App/components/Viewport/Features.test.jsx +124 -0
- package/src/App/components/Viewport/MapStatus.jsx +0 -4
- package/src/App/components/Viewport/Viewport.jsx +35 -29
- package/src/App/components/Viewport/Viewport.module.scss +7 -21
- package/src/App/components/Viewport/Viewport.test.jsx +108 -65
- package/src/App/controls/keyboardActions.js +9 -3
- package/src/App/controls/keyboardActions.test.js +122 -87
- package/src/App/controls/keyboardShortcuts.js +1 -14
- package/src/App/hooks/useFeatureFocus.js +199 -0
- package/src/App/hooks/useFeatureFocus.test.js +635 -0
- package/src/App/hooks/useFeatureItems.js +30 -0
- package/src/App/hooks/useFeatureItems.test.js +97 -0
- package/src/App/hooks/useFocusVisible.js +4 -7
- package/src/App/hooks/useFocusVisible.test.js +6 -6
- package/src/App/hooks/useKeyboardHint.js +9 -34
- package/src/App/hooks/useKeyboardHint.test.js +34 -84
- package/src/App/hooks/useKeyboardShortcuts.js +8 -5
- package/src/App/hooks/useKeyboardShortcuts.test.js +16 -12
- package/src/App/hooks/useLayoutMeasurements.js +10 -4
- package/src/App/hooks/useLayoutMeasurements.test.js +30 -0
- package/src/App/hooks/useMarkerCursor.js +33 -0
- package/src/App/hooks/useMarkerCursor.test.js +87 -0
- package/src/App/hooks/useMarkersAPI.js +32 -9
- package/src/App/hooks/useMarkersAPI.test.js +162 -94
- package/src/App/layout/Layout.jsx +2 -0
- package/src/App/layout/Layout.test.jsx +3 -0
- package/src/App/registry/keyboardShortcutRegistry.js +3 -2
- package/src/App/registry/keyboardShortcutRegistry.test.js +6 -8
- package/src/App/renderer/mapButtons.js +5 -1
- package/src/App/renderer/mapButtons.test.js +37 -1
- package/src/App/store/ServiceProvider.jsx +4 -1
- package/src/App/store/ServiceProvider.test.jsx +11 -0
- package/src/App/store/appActionsMap.js +5 -1
- package/src/App/store/appActionsMap.test.js +13 -0
- package/src/App/store/appReducer.js +1 -0
- package/src/App/store/mapActionsMap.js +2 -1
- package/src/InteractiveMap/InteractiveMap.js +12 -0
- package/src/InteractiveMap/InteractiveMap.test.js +2 -0
- package/src/config/appConfig.js +3 -1
- package/src/config/appConfig.test.js +4 -0
- package/src/config/defaults.js +1 -1
- package/src/config/events.js +8 -0
- package/src/config/mapTheme.js +8 -4
- package/src/config/symbolConfig.js +23 -16
- package/src/scss/main.scss +3 -0
- package/src/scss/tools/_border-focus.scss +0 -1
- package/src/services/eventBus.js +15 -0
- package/src/services/eventBus.test.js +11 -0
- package/src/services/hints.js +47 -0
- package/src/services/hints.test.js +110 -0
- package/src/services/patternRegistry.js +69 -1
- package/src/services/patternRegistry.test.js +112 -1
- package/src/services/reverseGeocode.js +4 -0
- package/src/services/reverseGeocode.test.js +11 -1
- package/src/services/symbolRegistry.js +152 -17
- package/src/services/symbolRegistry.test.js +141 -31
- package/src/types.js +71 -14
- package/src/utils/constrainKeyboardFocus.js +5 -5
- package/src/utils/detectInterfaceType.js +27 -5
- package/src/utils/detectInterfaceType.test.js +29 -3
- package/src/utils/patternUtils.js +4 -67
- package/src/utils/patternUtils.test.js +1 -123
- package/src/utils/symbolUtils.js +11 -13
- package/src/utils/symbolUtils.test.js +18 -26
- package/plugins/interact/dist/css/index.css +0 -1
- package/plugins/interact/src/interact.scss +0 -24
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
import { EVENTS } from '../../../../src/config/events.js'
|
|
3
|
+
import { isStandaloneLabel } from '../../../../src/utils/symbolUtils.js'
|
|
4
|
+
import { buildLayerConfigMap } from '../utils/featureQueries.js'
|
|
5
|
+
|
|
6
|
+
const getFeatureId = (feature, config) =>
|
|
7
|
+
config ? (feature.properties?.[config.idProperty] ?? feature.id) : null
|
|
8
|
+
|
|
9
|
+
const isInViewport = (el) => {
|
|
10
|
+
const container = el.closest('.im-c-viewport__markers')
|
|
11
|
+
if (!container) {
|
|
12
|
+
return false
|
|
13
|
+
}
|
|
14
|
+
const containerRect = container.getBoundingClientRect()
|
|
15
|
+
const { left, right, top, bottom } = el.getBoundingClientRect()
|
|
16
|
+
return right > containerRect.left && left < containerRect.right &&
|
|
17
|
+
bottom > containerRect.top && top < containerRect.bottom
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const collectVisibleMarkers = (markers) => {
|
|
21
|
+
const items = []
|
|
22
|
+
for (const marker of markers.items) {
|
|
23
|
+
if (!marker.label) { continue }
|
|
24
|
+
const el = markers.markerRefs?.get(marker.id)
|
|
25
|
+
if (!isStandaloneLabel(marker) && el && isInViewport(el)) {
|
|
26
|
+
items.push({ id: marker.id, label: marker.label })
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return items
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const toFeatureItem = (feature, layerConfigMap, seenIds) => {
|
|
33
|
+
const config = layerConfigMap[feature.layer?.id]
|
|
34
|
+
if (!config?.labelProperty) {
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
const id = getFeatureId(feature, config)
|
|
38
|
+
const stringId = id == null ? null : String(id)
|
|
39
|
+
if (stringId == null || seenIds.has(stringId)) {
|
|
40
|
+
return null
|
|
41
|
+
}
|
|
42
|
+
seenIds.add(stringId)
|
|
43
|
+
const label = feature.properties?.[config.labelProperty] ?? stringId
|
|
44
|
+
return { id: stringId, label }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const collectVisibleFeatures = (mapProvider, layers) => {
|
|
48
|
+
const items = []
|
|
49
|
+
const seenIds = new Set()
|
|
50
|
+
const layerIds = layers.map(layer => layer.layerId)
|
|
51
|
+
const layerConfigMap = buildLayerConfigMap(layers)
|
|
52
|
+
const features = mapProvider.getVisibleFeatures(layerIds)
|
|
53
|
+
for (const feature of features) {
|
|
54
|
+
const item = toFeatureItem(feature, layerConfigMap, seenIds)
|
|
55
|
+
if (item) {
|
|
56
|
+
items.push(item)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return items
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const findFeatureById = (features, layerConfigMap, targetId) => {
|
|
63
|
+
for (const feature of features) {
|
|
64
|
+
const config = layerConfigMap[feature.layer?.id]
|
|
65
|
+
const rawId = getFeatureId(feature, config)
|
|
66
|
+
if (rawId != null && String(rawId) === String(targetId)) {
|
|
67
|
+
return { feature, config, rawId }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return null
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Rebuilds the keyboard-navigable item list whenever the map moves or data changes.
|
|
75
|
+
* Collects visible markers (by DOM visibility) and visible features (by viewport query),
|
|
76
|
+
* then emits MAP_SET_FEATURES so the listbox stays in sync with what the user can see.
|
|
77
|
+
*/
|
|
78
|
+
function useItemListSync ({ markers, interactionModes, layers, mapProvider, multiSelect, eventBus }) {
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const handleMoveEnd = () => {
|
|
81
|
+
const items = []
|
|
82
|
+
if (interactionModes?.includes('selectMarker')) {
|
|
83
|
+
items.push(...collectVisibleMarkers(markers))
|
|
84
|
+
}
|
|
85
|
+
if (interactionModes?.includes('selectFeature') && layers.length > 0) {
|
|
86
|
+
items.push(...collectVisibleFeatures(mapProvider, layers))
|
|
87
|
+
}
|
|
88
|
+
eventBus.emit(EVENTS.MAP_SET_FEATURES, { items, multiselectable: multiSelect })
|
|
89
|
+
}
|
|
90
|
+
handleMoveEnd()
|
|
91
|
+
eventBus.on(EVENTS.MAP_MOVE_END, handleMoveEnd)
|
|
92
|
+
eventBus.on(EVENTS.MAP_DATA_CHANGE, handleMoveEnd)
|
|
93
|
+
return () => {
|
|
94
|
+
eventBus.off(EVENTS.MAP_MOVE_END, handleMoveEnd)
|
|
95
|
+
eventBus.off(EVENTS.MAP_DATA_CHANGE, handleMoveEnd)
|
|
96
|
+
}
|
|
97
|
+
}, [markers, interactionModes, layers, mapProvider, multiSelect, eventBus])
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Listens for MAP_SET_ACTIVE_FEATURE and resolves the active item to its full feature/marker data,
|
|
102
|
+
* storing it in both a ref (for synchronous access) and plugin state (for highlight rendering).
|
|
103
|
+
* Shows the keyboard cursor ring without firing interact:selectionchange — committing the item
|
|
104
|
+
* to the real selection only happens when the user presses Enter/Space.
|
|
105
|
+
*/
|
|
106
|
+
function useActiveItemHandler ({ markers, interactionModes, layers, mapProvider, eventBus, dispatch, listboxActiveItemRef }) {
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
const handle = ({ id }) => {
|
|
109
|
+
if (id === null) {
|
|
110
|
+
listboxActiveItemRef.current = null
|
|
111
|
+
dispatch({ type: 'SET_LISTBOX_ACTIVE', payload: null })
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
const markerMatch = markers.items.find(m => m.id === id)
|
|
115
|
+
if (markerMatch) {
|
|
116
|
+
listboxActiveItemRef.current = { id, isMarker: true }
|
|
117
|
+
dispatch({ type: 'SET_LISTBOX_ACTIVE', payload: null })
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
if (interactionModes?.includes('selectFeature') && layers.length > 0) {
|
|
121
|
+
const layerIds = layers.map(layer => layer.layerId)
|
|
122
|
+
const layerConfigMap = buildLayerConfigMap(layers)
|
|
123
|
+
const features = mapProvider.getVisibleFeatures(layerIds)
|
|
124
|
+
const match = findFeatureById(features, layerConfigMap, id)
|
|
125
|
+
if (match) {
|
|
126
|
+
const payload = {
|
|
127
|
+
featureId: match.rawId,
|
|
128
|
+
layerId: match.config.layerId,
|
|
129
|
+
idProperty: match.config.idProperty,
|
|
130
|
+
geometry: match.feature.geometry
|
|
131
|
+
}
|
|
132
|
+
listboxActiveItemRef.current = { id, isMarker: false, ...payload, properties: match.feature.properties }
|
|
133
|
+
dispatch({ type: 'SET_LISTBOX_ACTIVE', payload })
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
eventBus.on(EVENTS.MAP_SET_ACTIVE_FEATURE, handle)
|
|
138
|
+
return () => { eventBus.off(EVENTS.MAP_SET_ACTIVE_FEATURE, handle) }
|
|
139
|
+
}, [markers, interactionModes, layers, mapProvider, eventBus, dispatch, listboxActiveItemRef])
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Handles MAP_SELECT_FEATURE (Enter/Space keypress) by promoting the currently active
|
|
144
|
+
* listbox item to a confirmed selection, dispatching TOGGLE_SELECTED_FEATURES or
|
|
145
|
+
* TOGGLE_SELECTED_MARKERS and triggering interact:selectionchange downstream.
|
|
146
|
+
*/
|
|
147
|
+
function useSelectItemHandler ({ eventBus, dispatch, listboxActiveItemRef, multiSelect }) {
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
const handleConfirm = () => {
|
|
150
|
+
const item = listboxActiveItemRef.current
|
|
151
|
+
if (!item) {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
if (item.isMarker) {
|
|
155
|
+
dispatch({ type: 'TOGGLE_SELECTED_MARKERS', payload: { markerId: item.id, multiSelect } })
|
|
156
|
+
} else {
|
|
157
|
+
const { featureId, layerId, idProperty, geometry, properties } = item
|
|
158
|
+
dispatch({
|
|
159
|
+
type: 'TOGGLE_SELECTED_FEATURES',
|
|
160
|
+
payload: { featureId, layerId, idProperty, geometry, properties, multiSelect, replaceAll: !multiSelect }
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
eventBus.on(EVENTS.MAP_SELECT_FEATURE, handleConfirm)
|
|
165
|
+
return () => { eventBus.off(EVENTS.MAP_SELECT_FEATURE, handleConfirm) }
|
|
166
|
+
}, [eventBus, dispatch, listboxActiveItemRef, multiSelect])
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Orchestrates the keyboard-accessible listbox for the interact plugin.
|
|
171
|
+
*
|
|
172
|
+
* Composes three concerns:
|
|
173
|
+
* - Item list sync — keeps the listbox populated with currently visible markers and features
|
|
174
|
+
* - Active item resolution — translates a listbox cursor position into full feature/marker data
|
|
175
|
+
* - Selection confirmation — commits the active item to the selection on Enter/Space
|
|
176
|
+
*
|
|
177
|
+
* @param {{ mapState: object, pluginState: object, services: object, mapProvider: object }} params
|
|
178
|
+
*/
|
|
179
|
+
export function useMapItemList ({ mapState, pluginState, services, mapProvider }) {
|
|
180
|
+
const { markers } = mapState
|
|
181
|
+
const { dispatch, interactionModes, layers, multiSelect } = pluginState
|
|
182
|
+
const { eventBus } = services
|
|
183
|
+
const listboxActiveItemRef = useRef(null)
|
|
184
|
+
useItemListSync({ markers, interactionModes, layers, mapProvider, multiSelect, eventBus })
|
|
185
|
+
useActiveItemHandler({ markers, interactionModes, layers, mapProvider, eventBus, dispatch, listboxActiveItemRef })
|
|
186
|
+
useSelectItemHandler({ eventBus, dispatch, listboxActiveItemRef, multiSelect })
|
|
187
|
+
}
|