@salt-ds/lab 1.0.0-alpha.96 → 1.0.0-alpha.97

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 (78) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/css/salt-lab.css +1 -201
  3. package/dist-cjs/common-hooks/useSelection.js +6 -3
  4. package/dist-cjs/common-hooks/useSelection.js.map +1 -1
  5. package/dist-cjs/index.js +0 -6
  6. package/dist-cjs/index.js.map +1 -1
  7. package/dist-cjs/list/useList.js +7 -1
  8. package/dist-cjs/list/useList.js.map +1 -1
  9. package/dist-es/common-hooks/useSelection.js +6 -3
  10. package/dist-es/common-hooks/useSelection.js.map +1 -1
  11. package/dist-es/index.js +0 -3
  12. package/dist-es/index.js.map +1 -1
  13. package/dist-es/list/useList.js +7 -1
  14. package/dist-es/list/useList.js.map +1 -1
  15. package/dist-types/index.d.ts +0 -1
  16. package/package.json +2 -2
  17. package/dist-cjs/toolbar-next/ToolbarContentNext.css.js +0 -6
  18. package/dist-cjs/toolbar-next/ToolbarContentNext.css.js.map +0 -1
  19. package/dist-cjs/toolbar-next/ToolbarContentNext.js +0 -32
  20. package/dist-cjs/toolbar-next/ToolbarContentNext.js.map +0 -1
  21. package/dist-cjs/toolbar-next/ToolbarNext.css.js +0 -6
  22. package/dist-cjs/toolbar-next/ToolbarNext.css.js.map +0 -1
  23. package/dist-cjs/toolbar-next/ToolbarNext.js +0 -394
  24. package/dist-cjs/toolbar-next/ToolbarNext.js.map +0 -1
  25. package/dist-cjs/toolbar-next/ToolbarNextOverflow.css.js +0 -6
  26. package/dist-cjs/toolbar-next/ToolbarNextOverflow.css.js.map +0 -1
  27. package/dist-cjs/toolbar-next/ToolbarNextOverflow.js +0 -706
  28. package/dist-cjs/toolbar-next/ToolbarNextOverflow.js.map +0 -1
  29. package/dist-cjs/toolbar-next/ToolbarNextOverflowFloatingBoundary.js +0 -165
  30. package/dist-cjs/toolbar-next/ToolbarNextOverflowFloatingBoundary.js.map +0 -1
  31. package/dist-cjs/toolbar-next/TooltrayNext.css.js +0 -6
  32. package/dist-cjs/toolbar-next/TooltrayNext.css.js.map +0 -1
  33. package/dist-cjs/toolbar-next/TooltrayNext.js +0 -55
  34. package/dist-cjs/toolbar-next/TooltrayNext.js.map +0 -1
  35. package/dist-cjs/toolbar-next/toolbarNextKeyboardUtils.js +0 -409
  36. package/dist-cjs/toolbar-next/toolbarNextKeyboardUtils.js.map +0 -1
  37. package/dist-cjs/toolbar-next/toolbarNextUtils.js +0 -215
  38. package/dist-cjs/toolbar-next/toolbarNextUtils.js.map +0 -1
  39. package/dist-cjs/toolbar-next/useToolbarNextKeyboardNavigation.js +0 -312
  40. package/dist-cjs/toolbar-next/useToolbarNextKeyboardNavigation.js.map +0 -1
  41. package/dist-cjs/toolbar-next/useToolbarNextOverflow.js +0 -745
  42. package/dist-cjs/toolbar-next/useToolbarNextOverflow.js.map +0 -1
  43. package/dist-es/toolbar-next/ToolbarContentNext.css.js +0 -4
  44. package/dist-es/toolbar-next/ToolbarContentNext.css.js.map +0 -1
  45. package/dist-es/toolbar-next/ToolbarContentNext.js +0 -30
  46. package/dist-es/toolbar-next/ToolbarContentNext.js.map +0 -1
  47. package/dist-es/toolbar-next/ToolbarNext.css.js +0 -4
  48. package/dist-es/toolbar-next/ToolbarNext.css.js.map +0 -1
  49. package/dist-es/toolbar-next/ToolbarNext.js +0 -392
  50. package/dist-es/toolbar-next/ToolbarNext.js.map +0 -1
  51. package/dist-es/toolbar-next/ToolbarNextOverflow.css.js +0 -4
  52. package/dist-es/toolbar-next/ToolbarNextOverflow.css.js.map +0 -1
  53. package/dist-es/toolbar-next/ToolbarNextOverflow.js +0 -701
  54. package/dist-es/toolbar-next/ToolbarNextOverflow.js.map +0 -1
  55. package/dist-es/toolbar-next/ToolbarNextOverflowFloatingBoundary.js +0 -159
  56. package/dist-es/toolbar-next/ToolbarNextOverflowFloatingBoundary.js.map +0 -1
  57. package/dist-es/toolbar-next/TooltrayNext.css.js +0 -4
  58. package/dist-es/toolbar-next/TooltrayNext.css.js.map +0 -1
  59. package/dist-es/toolbar-next/TooltrayNext.js +0 -53
  60. package/dist-es/toolbar-next/TooltrayNext.js.map +0 -1
  61. package/dist-es/toolbar-next/toolbarNextKeyboardUtils.js +0 -390
  62. package/dist-es/toolbar-next/toolbarNextKeyboardUtils.js.map +0 -1
  63. package/dist-es/toolbar-next/toolbarNextUtils.js +0 -211
  64. package/dist-es/toolbar-next/toolbarNextUtils.js.map +0 -1
  65. package/dist-es/toolbar-next/useToolbarNextKeyboardNavigation.js +0 -310
  66. package/dist-es/toolbar-next/useToolbarNextKeyboardNavigation.js.map +0 -1
  67. package/dist-es/toolbar-next/useToolbarNextOverflow.js +0 -743
  68. package/dist-es/toolbar-next/useToolbarNextOverflow.js.map +0 -1
  69. package/dist-types/toolbar-next/ToolbarContentNext.d.ts +0 -11
  70. package/dist-types/toolbar-next/ToolbarNext.d.ts +0 -12
  71. package/dist-types/toolbar-next/ToolbarNextOverflow.d.ts +0 -34
  72. package/dist-types/toolbar-next/ToolbarNextOverflowFloatingBoundary.d.ts +0 -16
  73. package/dist-types/toolbar-next/TooltrayNext.d.ts +0 -37
  74. package/dist-types/toolbar-next/index.d.ts +0 -3
  75. package/dist-types/toolbar-next/toolbarNextKeyboardUtils.d.ts +0 -39
  76. package/dist-types/toolbar-next/toolbarNextUtils.d.ts +0 -42
  77. package/dist-types/toolbar-next/useToolbarNextKeyboardNavigation.d.ts +0 -42
  78. package/dist-types/toolbar-next/useToolbarNextOverflow.d.ts +0 -37
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @salt-ds/lab
2
2
 
3
+ ## 1.0.0-alpha.97
4
+
5
+ ### Minor Changes
6
+
7
+ - 2516755: Removed `ToolbarNext`, `ToolbarContentNext`, and `TooltrayNext` from lab and promoted to core. As part of the promotion the components were renamed e.g., `ToolbarNext` is now `Toolbar`.
8
+
9
+ The legacy `Toolbar` and `Tooltray` exports in lab are unchanged.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [906c94e]
14
+ - Updated dependencies [2516755]
15
+ - Updated dependencies [027f8c4]
16
+ - Updated dependencies [027f8c4]
17
+ - @salt-ds/core@1.65.0
18
+
3
19
  ## 1.0.0-alpha.96
4
20
 
5
21
  ### Minor Changes
package/css/salt-lab.css CHANGED
@@ -3148,206 +3148,6 @@
3148
3148
  flex-basis: 0;
3149
3149
  }
3150
3150
 
3151
- /* src/toolbar-next/ToolbarContentNext.css */
3152
- .saltToolbarContentNext {
3153
- display: flex;
3154
- align-items: center;
3155
- gap: var(--salt-spacing-100);
3156
- min-width: 0;
3157
- flex-shrink: 0;
3158
- }
3159
- .saltToolbarContentNext[data-position=start] {
3160
- justify-content: flex-start;
3161
- }
3162
- .saltToolbarContentNext[data-position=center] {
3163
- justify-content: center;
3164
- }
3165
- .saltToolbarContentNext[data-position=end] {
3166
- justify-content: flex-end;
3167
- }
3168
- .saltToolbarContentNext[data-implicit] > .saltTooltrayNext[data-align=center],
3169
- .saltToolbarContentNext[data-implicit] > .saltTooltrayNext[data-align=end] {
3170
- margin-inline-start: 0;
3171
- margin-inline-end: 0;
3172
- }
3173
-
3174
- /* src/toolbar-next/ToolbarNext.css */
3175
- .saltToolbarNext {
3176
- box-sizing: border-box;
3177
- inline-size: 100%;
3178
- min-width: 0;
3179
- position: relative;
3180
- }
3181
- .saltToolbarNext-layout {
3182
- align-items: center;
3183
- --saltToolbarNext-band-gap: var(--salt-spacing-100);
3184
- }
3185
- .saltToolbarNext-layout:not([data-centered]) {
3186
- display: flex;
3187
- column-gap: var(--saltToolbarNext-band-gap);
3188
- }
3189
- .saltToolbarNext-layout[data-centered] {
3190
- display: grid;
3191
- grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
3192
- }
3193
- .saltToolbarNext-band {
3194
- display: flex;
3195
- align-items: center;
3196
- gap: var(--saltToolbarNext-band-gap);
3197
- min-width: 0;
3198
- }
3199
- .saltToolbarNext-layout:not([data-centered]) > .saltToolbarNext-band[data-band-position=end] {
3200
- justify-content: flex-end;
3201
- margin-inline-start: auto;
3202
- }
3203
- .saltToolbarNext-layout[data-centered] > .saltToolbarNext-band[data-band-position=start] {
3204
- grid-column: 1;
3205
- }
3206
- .saltToolbarNext-layout[data-centered] > .saltToolbarNext-band[data-band-position=center] {
3207
- grid-column: 2;
3208
- justify-content: center;
3209
- }
3210
- .saltToolbarNext-layout[data-centered] > .saltToolbarNext-band[data-band-position=end] {
3211
- grid-column: 3;
3212
- justify-content: flex-end;
3213
- }
3214
- .saltToolbarNext-fallback {
3215
- display: flex;
3216
- align-items: center;
3217
- gap: var(--salt-spacing-100);
3218
- }
3219
- .saltToolbarNext-layout > * {
3220
- min-width: 0;
3221
- }
3222
- .saltToolbarNext-primary {
3223
- --toolbarNext-background: var(--salt-container-primary-background);
3224
- --toolbarNext-borderColor: var(--salt-container-primary-borderColor);
3225
- }
3226
- .saltToolbarNext-secondary {
3227
- --toolbarNext-background: var(--salt-container-secondary-background);
3228
- --toolbarNext-borderColor: var(--salt-container-secondary-borderColor);
3229
- }
3230
- .saltToolbarNext-tertiary {
3231
- --toolbarNext-background: var(--salt-container-tertiary-background);
3232
- --toolbarNext-borderColor: var(--salt-container-tertiary-borderColor);
3233
- }
3234
- .saltToolbarNext-bordered {
3235
- background: var(--saltToolbarNext-background, var(--toolbarNext-background));
3236
- border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--saltToolbarNext-borderColor, var(--toolbarNext-borderColor));
3237
- border-radius: var(--salt-palette-corner, 0);
3238
- padding: var(--salt-spacing-100);
3239
- }
3240
- .saltToolbarNext-transparent {
3241
- background: transparent;
3242
- border: none;
3243
- padding: 0;
3244
- }
3245
- .saltToolbarNext-measurements {
3246
- display: flex;
3247
- gap: var(--salt-spacing-100);
3248
- position: absolute;
3249
- visibility: hidden;
3250
- pointer-events: none;
3251
- inset: 0 auto auto 0;
3252
- block-size: 0;
3253
- overflow: hidden;
3254
- }
3255
- .saltToolbarNext-measureTrigger {
3256
- white-space: nowrap;
3257
- }
3258
-
3259
- /* src/toolbar-next/ToolbarNextOverflow.css */
3260
- .saltToolbarNextOverflow-content {
3261
- position: relative;
3262
- }
3263
- .saltToolbarNextOverflow-slot,
3264
- .saltToolbarNextOverflow-panelItem {
3265
- align-items: center;
3266
- display: flex;
3267
- flex-shrink: 0;
3268
- gap: var(--salt-spacing-100);
3269
- min-width: 0;
3270
- }
3271
- .saltToolbarNextOverflow-slot[data-align=end] {
3272
- margin-inline-start: auto;
3273
- }
3274
- .saltToolbarNextOverflow-slot[data-align=center] {
3275
- margin-inline-start: auto;
3276
- margin-inline-end: auto;
3277
- }
3278
- .saltToolbarNextOverflow-item {
3279
- align-items: center;
3280
- display: flex;
3281
- flex-shrink: 0;
3282
- min-width: 0;
3283
- }
3284
- .saltToolbarNextOverflow-menu {
3285
- display: flex;
3286
- flex-shrink: 0;
3287
- }
3288
- .saltToolbarNextOverflow-itemHost,
3289
- .saltToolbarNextOverflow-contentHost {
3290
- display: contents;
3291
- }
3292
- .saltToolbarNextOverflow-trigger {
3293
- white-space: nowrap;
3294
- }
3295
- .saltToolbarNextOverflow-panel {
3296
- background: var(--salt-container-primary-background);
3297
- border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--salt-selectable-borderColor-selected);
3298
- border-radius: var(--salt-palette-corner, 0);
3299
- box-shadow: var(--salt-overlayable-shadow-popout);
3300
- box-sizing: border-box;
3301
- max-width: min(32rem, calc(100vw - var(--salt-spacing-300)));
3302
- overflow: auto;
3303
- position: absolute;
3304
- z-index: var(--salt-zIndex-flyover);
3305
- }
3306
- .saltToolbarNextOverflow-floatingDescendant.saltToolbarNextOverflow-floatingDescendant {
3307
- z-index: calc(var(--salt-zIndex-flyover) + var(--salt-zIndex-default));
3308
- }
3309
- .saltToolbarNextOverflow-panelContent {
3310
- align-items: center;
3311
- display: flex;
3312
- flex-wrap: wrap;
3313
- gap: var(--salt-spacing-100);
3314
- max-width: inherit;
3315
- min-width: max-content;
3316
- padding: var(--salt-spacing-100);
3317
- }
3318
- .saltToolbarNextOverflow-panel .saltTooltrayNext[data-align=center],
3319
- .saltToolbarNextOverflow-panel .saltTooltrayNext[data-align=end] {
3320
- margin-inline-start: 0;
3321
- margin-inline-end: 0;
3322
- }
3323
- .saltToolbarNextOverflow-panel .saltTooltrayNext > * {
3324
- inline-size: auto;
3325
- }
3326
- .saltToolbarNextOverflow-content > .saltToolbarNextOverflow-slot .saltTooltrayNext[data-align=center],
3327
- .saltToolbarNextOverflow-content > .saltToolbarNextOverflow-slot .saltTooltrayNext[data-align=end] {
3328
- margin-inline-start: 0;
3329
- margin-inline-end: 0;
3330
- }
3331
-
3332
- /* src/toolbar-next/TooltrayNext.css */
3333
- .saltTooltrayNext {
3334
- display: flex;
3335
- align-items: center;
3336
- flex: 0 0 auto;
3337
- gap: var(--salt-spacing-100);
3338
- min-width: 0;
3339
- }
3340
- .saltTooltrayNext > * {
3341
- flex-shrink: 0;
3342
- }
3343
- .saltTooltrayNext[data-align=end] {
3344
- margin-inline-start: auto;
3345
- }
3346
- .saltTooltrayNext[data-align=center] {
3347
- margin-inline-start: auto;
3348
- margin-inline-end: auto;
3349
- }
3350
-
3351
3151
  /* src/window/ElectronWindow.css */
3352
3152
  .saltWindow {
3353
3153
  --saltDialog-boxShadow: none;
@@ -3458,4 +3258,4 @@
3458
3258
  margin: calc(var(--salt-size-unit) / 2) 0;
3459
3259
  }
3460
3260
 
3461
- /* src/e4ab0e63-880d-4ad2-9759-4acceca8a38d.css */
3261
+ /* src/8f16bdce-6a2c-43c5-bef1-c547bffcc9de.css */
@@ -2,6 +2,7 @@
2
2
 
3
3
  var core = require('@salt-ds/core');
4
4
  var react = require('react');
5
+ var listDomUtils = require('./list-dom-utils.js');
5
6
 
6
7
  const defaultSelectionKeys = ["Enter", " "];
7
8
  const isSelectable = (item) => item && item.disabled !== true && item.selectable !== false;
@@ -157,19 +158,21 @@ const useSelection = ({
157
158
  );
158
159
  const handleClick = react.useCallback(
159
160
  (evt) => {
160
- const item = indexPositions[highlightedIdx];
161
+ const targetIdx = listDomUtils.closestListItemIndex(evt.target);
162
+ const idx = targetIdx >= 0 ? targetIdx : highlightedIdx;
163
+ const item = indexPositions[idx];
161
164
  if (!disableSelection && isSelectable(item)) {
162
165
  evt.preventDefault();
163
166
  evt.stopPropagation();
164
167
  selectItemAtIndex(
165
168
  evt,
166
- highlightedIdx,
169
+ idx,
167
170
  item,
168
171
  evt.shiftKey,
169
172
  evt.ctrlKey || evt.metaKey
170
173
  );
171
174
  if (isExtendedSelect) {
172
- lastActive.current = highlightedIdx;
175
+ lastActive.current = idx;
173
176
  }
174
177
  }
175
178
  },
@@ -1 +1 @@
1
- {"version":3,"file":"useSelection.js","sources":["../src/common-hooks/useSelection.ts"],"sourcesContent":["import { useControlled } from \"@salt-ds/core\";\nimport {\n type KeyboardEvent,\n type MouseEvent,\n type SyntheticEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport type { CollectionItem } from \"./collectionTypes\";\nimport type {\n SelectionHookProps,\n SelectionHookResult,\n SelectionStrategy,\n SingleSelectionStrategy,\n} from \"./selectionTypes\";\n\nexport const CHECKBOX = \"checkbox\";\n\nexport const GROUP_SELECTION_NONE = \"none\";\nexport const GROUP_SELECTION_SINGLE = \"single\";\nexport const GROUP_SELECTION_CASCADE = \"cascade\";\n\nexport type GroupSelectionMode = \"none\" | \"single\" | \"cascade\";\n\nconst defaultSelectionKeys = [\"Enter\", \" \"];\n\nconst isSelectable = (item?: CollectionItem<unknown>) =>\n item && item.disabled !== true && item.selectable !== false;\n\nconst byItemIndex = (\n i1: CollectionItem<unknown>,\n i2: CollectionItem<unknown>,\n) => (i1.index ?? 0) - (i2.index ?? 0);\n\nexport const groupSelectionEnabled = (\n groupSelection: GroupSelectionMode,\n): boolean => groupSelection && groupSelection !== GROUP_SELECTION_NONE;\n\nexport const useSelection = <\n Item,\n Selection extends SelectionStrategy = \"default\",\n>({\n defaultSelected,\n disableSelection = false,\n // groupSelection = GROUP_SELECTION_NONE,\n highlightedIdx,\n indexPositions,\n label: _label = \"\",\n onSelect,\n onSelectionChange,\n selected: selectedProp,\n selectionStrategy,\n selectionKeys = defaultSelectionKeys,\n tabToSelect,\n}: SelectionHookProps<Item, Selection>): SelectionHookResult<\n Item,\n Selection\n> => {\n type collectionItem = CollectionItem<Item>;\n\n const isDeselectable = selectionStrategy === \"deselectable\";\n const isMultipleSelect = selectionStrategy === \"multiple\";\n const isExtendedSelect = selectionStrategy === \"extended\";\n\n const lastActive = useRef(-1);\n\n const isSelectionEvent = useCallback(\n (evt: KeyboardEvent) => selectionKeys.includes(evt.key),\n [selectionKeys],\n );\n\n const emptyValue = useCallback(<\n Item,\n >(): Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[] => {\n type returnType = Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[];\n return isMultipleSelect || isExtendedSelect\n ? ([] as unknown as returnType)\n : (null as returnType);\n }, [isMultipleSelect, isExtendedSelect]);\n\n const [selected, setSelected] = useControlled<\n Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[]\n >({\n controlled: selectedProp,\n default: defaultSelected ?? emptyValue(),\n name: \"UseSelection\",\n state: \"selected\",\n });\n\n const isItemSelected = useCallback(\n (item: collectionItem) => {\n return Array.isArray(selected)\n ? selected.includes(item)\n : selected === item;\n },\n [selected],\n );\n\n const selectDefault = useCallback((item: collectionItem) => item, []);\n const selectDeselectable = useCallback(\n (item: collectionItem) => (isItemSelected(item) ? null : item),\n [isItemSelected],\n );\n const selectMultiple = useCallback(\n (item: collectionItem) => {\n const nextItems = isItemSelected(item)\n ? (selected as collectionItem[]).filter((i) => i !== item)\n : (selected as collectionItem[]).concat(item);\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [isItemSelected, selected],\n );\n const selectRange = useCallback(\n (idx: number, preserveExistingSelection?: boolean) => {\n const currentSelection = preserveExistingSelection\n ? (selected as collectionItem[])\n : ([] as collectionItem[]);\n\n const [lastSelectedItem] = (selected as collectionItem[]).slice(-1);\n const lastSelectedItemIndex = lastSelectedItem\n ? indexPositions.indexOf(lastSelectedItem)\n : 0;\n\n const startRegion = Math.min(idx, lastSelectedItemIndex);\n const endRegion = Math.max(idx, lastSelectedItemIndex);\n const rangeSelection = indexPositions.slice(startRegion, endRegion + 1);\n // concat the current selection with a new selection and remove duplicates for overlaps\n const nextItems = [...new Set([...currentSelection, ...rangeSelection])];\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [indexPositions, selected],\n );\n\n const selectItemAtIndex = useCallback(\n (\n evt: SyntheticEvent,\n idx: number,\n item: collectionItem,\n rangeSelect: boolean,\n preserveExistingSelection?: boolean,\n ) => {\n type returnType = Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[];\n let newSelected: returnType;\n if (isMultipleSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (isExtendedSelect) {\n if (preserveExistingSelection && !rangeSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (rangeSelect) {\n newSelected = selectRange(\n idx,\n preserveExistingSelection,\n ) as returnType;\n } else {\n newSelected = [item] as returnType;\n }\n } else if (isDeselectable) {\n newSelected = selectDeselectable(item) as returnType;\n } else {\n newSelected = selectDefault(item) as returnType;\n }\n\n if (newSelected !== selected) {\n setSelected(newSelected);\n }\n\n // We fire onSelect irrespective of whether selection changes\n onSelect?.(evt, item);\n\n if (newSelected !== selected) {\n if (onSelectionChange) {\n onSelectionChange(evt, newSelected);\n }\n }\n },\n [\n isMultipleSelect,\n isExtendedSelect,\n isDeselectable,\n selected,\n onSelect,\n selectMultiple,\n selectRange,\n selectDeselectable,\n selectDefault,\n onSelectionChange,\n ],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n const item = indexPositions[highlightedIdx];\n if (isSelectable(item)) {\n if (isSelectionEvent(evt) || (tabToSelect && evt.key === \"Tab\")) {\n // We do not inhibit Tab behaviour, if we are selecting on Tab then we apply\n // selection as a side effect of the Tab, not as a replacement for Tabbing.\n if (evt.key !== \"Tab\") {\n evt.preventDefault();\n }\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item,\n false,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n }\n },\n [\n indexPositions,\n highlightedIdx,\n isSelectionEvent,\n tabToSelect,\n selectItemAtIndex,\n isExtendedSelect,\n ],\n );\n\n const handleKeyboardNavigation = useCallback(\n (evt: KeyboardEvent, currentIndex: number) => {\n if (isExtendedSelect && evt.shiftKey) {\n const item = indexPositions[currentIndex];\n if (isSelectable(item)) {\n selectItemAtIndex(evt, currentIndex, item, true);\n }\n }\n },\n [isExtendedSelect, indexPositions, selectItemAtIndex],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n const item = indexPositions[highlightedIdx];\n if (!disableSelection && isSelectable(item)) {\n // if (!isCollapsibleItem(item)) {\n evt.preventDefault();\n evt.stopPropagation();\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item,\n evt.shiftKey,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = highlightedIdx;\n }\n // }\n }\n },\n [\n disableSelection,\n isExtendedSelect,\n highlightedIdx,\n indexPositions,\n selectItemAtIndex,\n ],\n );\n\n const listHandlers = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onKeyboardNavigation: handleKeyboardNavigation,\n };\n\n return {\n listHandlers,\n selected,\n setSelected,\n };\n};\n"],"names":["useRef","useCallback","useControlled"],"mappings":"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"}
1
+ {"version":3,"file":"useSelection.js","sources":["../src/common-hooks/useSelection.ts"],"sourcesContent":["import { useControlled } from \"@salt-ds/core\";\nimport {\n type KeyboardEvent,\n type MouseEvent,\n type SyntheticEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport type { CollectionItem } from \"./collectionTypes\";\nimport { closestListItemIndex } from \"./list-dom-utils\";\nimport type {\n SelectionHookProps,\n SelectionHookResult,\n SelectionStrategy,\n SingleSelectionStrategy,\n} from \"./selectionTypes\";\n\nexport const CHECKBOX = \"checkbox\";\n\nexport const GROUP_SELECTION_NONE = \"none\";\nexport const GROUP_SELECTION_SINGLE = \"single\";\nexport const GROUP_SELECTION_CASCADE = \"cascade\";\n\nexport type GroupSelectionMode = \"none\" | \"single\" | \"cascade\";\n\nconst defaultSelectionKeys = [\"Enter\", \" \"];\n\nconst isSelectable = (item?: CollectionItem<unknown>) =>\n item && item.disabled !== true && item.selectable !== false;\n\nconst byItemIndex = (\n i1: CollectionItem<unknown>,\n i2: CollectionItem<unknown>,\n) => (i1.index ?? 0) - (i2.index ?? 0);\n\nexport const groupSelectionEnabled = (\n groupSelection: GroupSelectionMode,\n): boolean => groupSelection && groupSelection !== GROUP_SELECTION_NONE;\n\nexport const useSelection = <\n Item,\n Selection extends SelectionStrategy = \"default\",\n>({\n defaultSelected,\n disableSelection = false,\n // groupSelection = GROUP_SELECTION_NONE,\n highlightedIdx,\n indexPositions,\n label: _label = \"\",\n onSelect,\n onSelectionChange,\n selected: selectedProp,\n selectionStrategy,\n selectionKeys = defaultSelectionKeys,\n tabToSelect,\n}: SelectionHookProps<Item, Selection>): SelectionHookResult<\n Item,\n Selection\n> => {\n type collectionItem = CollectionItem<Item>;\n\n const isDeselectable = selectionStrategy === \"deselectable\";\n const isMultipleSelect = selectionStrategy === \"multiple\";\n const isExtendedSelect = selectionStrategy === \"extended\";\n\n const lastActive = useRef(-1);\n\n const isSelectionEvent = useCallback(\n (evt: KeyboardEvent) => selectionKeys.includes(evt.key),\n [selectionKeys],\n );\n\n const emptyValue = useCallback(<\n Item,\n >(): Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[] => {\n type returnType = Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[];\n return isMultipleSelect || isExtendedSelect\n ? ([] as unknown as returnType)\n : (null as returnType);\n }, [isMultipleSelect, isExtendedSelect]);\n\n const [selected, setSelected] = useControlled<\n Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[]\n >({\n controlled: selectedProp,\n default: defaultSelected ?? emptyValue(),\n name: \"UseSelection\",\n state: \"selected\",\n });\n\n const isItemSelected = useCallback(\n (item: collectionItem) => {\n return Array.isArray(selected)\n ? selected.includes(item)\n : selected === item;\n },\n [selected],\n );\n\n const selectDefault = useCallback((item: collectionItem) => item, []);\n const selectDeselectable = useCallback(\n (item: collectionItem) => (isItemSelected(item) ? null : item),\n [isItemSelected],\n );\n const selectMultiple = useCallback(\n (item: collectionItem) => {\n const nextItems = isItemSelected(item)\n ? (selected as collectionItem[]).filter((i) => i !== item)\n : (selected as collectionItem[]).concat(item);\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [isItemSelected, selected],\n );\n const selectRange = useCallback(\n (idx: number, preserveExistingSelection?: boolean) => {\n const currentSelection = preserveExistingSelection\n ? (selected as collectionItem[])\n : ([] as collectionItem[]);\n\n const [lastSelectedItem] = (selected as collectionItem[]).slice(-1);\n const lastSelectedItemIndex = lastSelectedItem\n ? indexPositions.indexOf(lastSelectedItem)\n : 0;\n\n const startRegion = Math.min(idx, lastSelectedItemIndex);\n const endRegion = Math.max(idx, lastSelectedItemIndex);\n const rangeSelection = indexPositions.slice(startRegion, endRegion + 1);\n // concat the current selection with a new selection and remove duplicates for overlaps\n const nextItems = [...new Set([...currentSelection, ...rangeSelection])];\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [indexPositions, selected],\n );\n\n const selectItemAtIndex = useCallback(\n (\n evt: SyntheticEvent,\n idx: number,\n item: collectionItem,\n rangeSelect: boolean,\n preserveExistingSelection?: boolean,\n ) => {\n type returnType = Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[];\n let newSelected: returnType;\n if (isMultipleSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (isExtendedSelect) {\n if (preserveExistingSelection && !rangeSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (rangeSelect) {\n newSelected = selectRange(\n idx,\n preserveExistingSelection,\n ) as returnType;\n } else {\n newSelected = [item] as returnType;\n }\n } else if (isDeselectable) {\n newSelected = selectDeselectable(item) as returnType;\n } else {\n newSelected = selectDefault(item) as returnType;\n }\n\n if (newSelected !== selected) {\n setSelected(newSelected);\n }\n\n // We fire onSelect irrespective of whether selection changes\n onSelect?.(evt, item);\n\n if (newSelected !== selected) {\n if (onSelectionChange) {\n onSelectionChange(evt, newSelected);\n }\n }\n },\n [\n isMultipleSelect,\n isExtendedSelect,\n isDeselectable,\n selected,\n onSelect,\n selectMultiple,\n selectRange,\n selectDeselectable,\n selectDefault,\n onSelectionChange,\n ],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n const item = indexPositions[highlightedIdx];\n if (isSelectable(item)) {\n if (isSelectionEvent(evt) || (tabToSelect && evt.key === \"Tab\")) {\n // We do not inhibit Tab behaviour, if we are selecting on Tab then we apply\n // selection as a side effect of the Tab, not as a replacement for Tabbing.\n if (evt.key !== \"Tab\") {\n evt.preventDefault();\n }\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item,\n false,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n }\n },\n [\n indexPositions,\n highlightedIdx,\n isSelectionEvent,\n tabToSelect,\n selectItemAtIndex,\n isExtendedSelect,\n ],\n );\n\n const handleKeyboardNavigation = useCallback(\n (evt: KeyboardEvent, currentIndex: number) => {\n if (isExtendedSelect && evt.shiftKey) {\n const item = indexPositions[currentIndex];\n if (isSelectable(item)) {\n selectItemAtIndex(evt, currentIndex, item, true);\n }\n }\n },\n [isExtendedSelect, indexPositions, selectItemAtIndex],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n // Resolve the clicked item from the event target rather than relying on\n // `highlightedIdx`. The highlighted index is updated asynchronously from\n // a `mousemove` handler on the list; in fast/synthetic interactions\n // (notably Cypress `realClick`) the click can fire before React has\n // re-rendered with the updated highlight, which previously caused the\n // click to be silently ignored (root cause of flaky selection tests).\n const targetIdx = closestListItemIndex(evt.target as HTMLElement);\n const idx = targetIdx >= 0 ? targetIdx : highlightedIdx;\n const item = indexPositions[idx];\n if (!disableSelection && isSelectable(item)) {\n // if (!isCollapsibleItem(item)) {\n evt.preventDefault();\n evt.stopPropagation();\n selectItemAtIndex(\n evt,\n idx,\n item,\n evt.shiftKey,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = idx;\n }\n // }\n }\n },\n [\n disableSelection,\n isExtendedSelect,\n highlightedIdx,\n indexPositions,\n selectItemAtIndex,\n ],\n );\n\n const listHandlers = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onKeyboardNavigation: handleKeyboardNavigation,\n };\n\n return {\n listHandlers,\n selected,\n setSelected,\n };\n};\n"],"names":["useRef","useCallback","useControlled","closestListItemIndex"],"mappings":"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"}
package/dist-cjs/index.js CHANGED
@@ -128,9 +128,6 @@ var Toolbar = require('./toolbar/Toolbar.js');
128
128
  var ToolbarButton = require('./toolbar/ToolbarButton.js');
129
129
  var Tooltray = require('./toolbar/Tooltray.js');
130
130
  var ToolbarField = require('./toolbar/toolbar-field/ToolbarField.js');
131
- var ToolbarContentNext = require('./toolbar-next/ToolbarContentNext.js');
132
- var ToolbarNext = require('./toolbar-next/ToolbarNext.js');
133
- var TooltrayNext = require('./toolbar-next/TooltrayNext.js');
134
131
  var ElectronWindow = require('./window/ElectronWindow.js');
135
132
  var WindowContext = require('./window/WindowContext.js');
136
133
 
@@ -292,9 +289,6 @@ exports.Toolbar = Toolbar.Toolbar;
292
289
  exports.ToolbarButton = ToolbarButton.ToolbarButton;
293
290
  exports.Tooltray = Tooltray.Tooltray;
294
291
  exports.ToolbarField = ToolbarField.ToolbarField;
295
- exports.ToolbarContentNext = ToolbarContentNext.ToolbarContentNext;
296
- exports.ToolbarNext = ToolbarNext.ToolbarNext;
297
- exports.TooltrayNext = TooltrayNext.TooltrayNext;
298
292
  exports.ElectronWindow = ElectronWindow.ElectronWindow;
299
293
  exports.Window = WindowContext.Window;
300
294
  exports.WindowContext = WindowContext.WindowContext;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -180,7 +180,13 @@ const useList = ({
180
180
  onMouseLeave: navigationControlProps.onMouseLeave
181
181
  };
182
182
  const listHandlers = listHandlersProp || {
183
- onClick: selectionHook.listHandlers.onClick,
183
+ // Don't expose a click handler when the list is disabled. Previously,
184
+ // selection on disabled lists was prevented only as a side-effect of
185
+ // `handleMouseMove` gating on `disabled` (which kept `highlightedIdx` at
186
+ // -1, so `useSelection.handleClick` no-op'd). Now that `handleClick`
187
+ // resolves the clicked item directly from the event target, we must
188
+ // explicitly suppress the handler here.
189
+ onClick: disabled ? void 0 : selectionHook.listHandlers.onClick,
184
190
  // MouseEnter would be much better for this. There is a bug in Cypress
185
191
  // wheby it emits spurious MouseEnter (and MouseOver) events around
186
192
  // keypress events, which break many tests.
@@ -1 +1 @@
1
- {"version":3,"file":"useList.js","sources":["../src/list/useList.ts"],"sourcesContent":["import {\n isValidElement,\n type KeyboardEvent,\n type MouseEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport {\n type CollectionItem,\n closestListItemIndex,\n type ListHandlers,\n type SelectHandler,\n type SelectionChangeHandler,\n type SelectionStrategy,\n type SingleSelectionStrategy,\n useCollapsibleGroups,\n useKeyboardNavigation,\n useSelection,\n useTypeahead,\n useViewportTracking,\n} from \"../common-hooks\";\n\nimport type {\n ListControlProps,\n ListHookProps,\n ListHookResult,\n} from \"./listTypes\";\n\nexport const useList = <Item, Selection extends SelectionStrategy = \"default\">({\n collapsibleHeaders,\n collectionHook: dataHook,\n containerRef,\n contentRef,\n defaultHighlightedIndex,\n defaultSelected,\n disabled,\n disableAriaActiveDescendant,\n disableHighlightOnFocus,\n disableTypeToSelect,\n highlightedIndex: highlightedIndexProp,\n label = \"\",\n listHandlers: listHandlersProp,\n onSelect,\n onSelectionChange,\n onHighlight,\n onKeyboardNavigation,\n onKeyDown,\n restoreLastFocus,\n selected,\n selectionStrategy,\n selectionKeys,\n stickyHeaders,\n tabToSelect,\n}: ListHookProps<Item, Selection>): ListHookResult<Item, Selection> => {\n const lastSelection = useRef<typeof selected>(selected || defaultSelected);\n const handleKeyboardNavigation = (\n evt: KeyboardEvent<HTMLElement>,\n nextIndex: number,\n ) => {\n selectionHook.listHandlers.onKeyboardNavigation?.(evt, nextIndex);\n onKeyboardNavigation?.(evt, nextIndex);\n };\n\n // TODO where do these belong ?\n const handleSelect = useCallback<SelectHandler<CollectionItem<Item>>>(\n (evt, selectedItem) => {\n if (onSelect) {\n if (isValidElement(selectedItem.value)) {\n onSelect(evt, selectedItem.label as Item);\n } else if (selectedItem.value !== null) {\n onSelect(evt, selectedItem.value);\n }\n }\n },\n [onSelect],\n );\n\n const handleSelectionChange = useCallback<\n SelectionChangeHandler<CollectionItem<Item>, Selection>\n >(\n (evt, selected) => {\n if (onSelectionChange) {\n onSelectionChange(\n evt,\n (Array.isArray(selected)\n ? selected.map((s) => (isValidElement(s.value) ? s.label : s.value))\n : selected &&\n (isValidElement(selected.value)\n ? selected.label\n : selected.value)) as Selection extends SingleSelectionStrategy\n ? Item\n : Item[],\n );\n }\n },\n [onSelectionChange],\n );\n\n const {\n highlightedIndex,\n listProps: {\n onKeyDown: navigationKeyDown,\n onMouseMove: navigationMouseMove,\n ...navigationControlProps\n },\n setHighlightedIndex,\n ...keyboardHook\n } = useKeyboardNavigation<Item, Selection>({\n containerRef,\n defaultHighlightedIndex,\n disableHighlightOnFocus,\n highlightedIndex: highlightedIndexProp,\n indexPositions: dataHook.data,\n label,\n onHighlight,\n onKeyboardNavigation: handleKeyboardNavigation,\n restoreLastFocus,\n selected: lastSelection.current,\n });\n\n const collapsibleHook = useCollapsibleGroups({\n collapsibleHeaders,\n highlightedIdx: highlightedIndex,\n collectionHook: dataHook,\n });\n\n const selectionHook = useSelection<Item, Selection>({\n defaultSelected,\n highlightedIdx: highlightedIndex,\n indexPositions: dataHook.data,\n label,\n onSelect: handleSelect,\n onSelectionChange: handleSelectionChange,\n selected,\n selectionStrategy,\n selectionKeys,\n tabToSelect,\n });\n\n const { onKeyDown: typeaheadOnKeyDown } = useTypeahead<Item>({\n disableTypeToSelect,\n highlightedIdx: highlightedIndex,\n highlightItemAtIndex: setHighlightedIndex,\n typeToNavigate: true,\n items: dataHook.data,\n });\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (!evt.defaultPrevented) {\n typeaheadOnKeyDown?.(evt);\n }\n // We still let the keyboard navigation hook process the event even\n // if it has been handled by the typeahead hook. That is so it can\n // correctly manage the focusVisible state.\n navigationKeyDown(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listHandlers.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n collapsibleHook?.onKeyDown?.(evt);\n }\n\n if (!evt.defaultPrevented) {\n onKeyDown?.(evt);\n }\n },\n [\n collapsibleHook,\n navigationKeyDown,\n onKeyDown,\n selectionHook.listHandlers,\n typeaheadOnKeyDown,\n ],\n );\n\n // This is only appropriate when we are directly controlling a List,\n // not when a control is manipulating the list\n const { isScrolling, scrollIntoView } = useViewportTracking({\n containerRef,\n contentRef,\n highlightedIdx: highlightedIndex,\n indexPositions: dataHook.data,\n stickyHeaders,\n });\n\n const handleMouseMove = useCallback(\n (evt: MouseEvent) => {\n if (!isScrolling.current && !disabled) {\n navigationMouseMove();\n const idx = closestListItemIndex(evt.target as HTMLElement);\n if (idx !== highlightedIndex) {\n const item = dataHook.data[idx];\n if (!item || item.disabled) {\n setHighlightedIndex(-1);\n } else {\n setHighlightedIndex(idx);\n }\n }\n }\n },\n [\n isScrolling,\n disabled,\n setHighlightedIndex,\n navigationMouseMove,\n highlightedIndex,\n dataHook.data,\n ],\n );\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined ||\n highlightedIndex === -1 ||\n disableAriaActiveDescendant\n ? undefined\n : dataHook.data[highlightedIndex]?.id;\n\n // We need this on reEntry for navigation hook to handle focus\n lastSelection.current = selectionHook.selected;\n\n // controlProps ?\n const listControlProps: ListControlProps = {\n \"aria-activedescendant\": getActiveDescendant(),\n onBlur: navigationControlProps.onBlur,\n onFocus: navigationControlProps.onFocus,\n onKeyDown: handleKeyDown,\n onMouseDownCapture: navigationControlProps.onMouseDownCapture,\n onMouseLeave: navigationControlProps.onMouseLeave,\n };\n\n const listHandlers: ListHandlers = listHandlersProp || {\n onClick: selectionHook.listHandlers.onClick,\n // MouseEnter would be much better for this. There is a bug in Cypress\n // wheby it emits spurious MouseEnter (and MouseOver) events around\n // keypress events, which break many tests.\n onMouseMove: handleMouseMove,\n };\n\n return {\n focusVisible: keyboardHook.focusVisible,\n controlledHighlighting: keyboardHook.controlledHighlighting,\n highlightedIndex,\n keyboardNavigation: keyboardHook.keyboardNavigation,\n listHandlers,\n listItemHeaderHandlers: collapsibleHook,\n listControlProps,\n scrollIntoView,\n selected: selectionHook.selected,\n setHighlightedIndex,\n setIgnoreFocus: keyboardHook.setIgnoreFocus,\n setSelected: selectionHook.setSelected,\n };\n};\n"],"names":["useRef","useCallback","isValidElement","selected","useKeyboardNavigation","useCollapsibleGroups","useSelection","useTypeahead","useViewportTracking","closestListItemIndex"],"mappings":"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"}
1
+ {"version":3,"file":"useList.js","sources":["../src/list/useList.ts"],"sourcesContent":["import {\n isValidElement,\n type KeyboardEvent,\n type MouseEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport {\n type CollectionItem,\n closestListItemIndex,\n type ListHandlers,\n type SelectHandler,\n type SelectionChangeHandler,\n type SelectionStrategy,\n type SingleSelectionStrategy,\n useCollapsibleGroups,\n useKeyboardNavigation,\n useSelection,\n useTypeahead,\n useViewportTracking,\n} from \"../common-hooks\";\n\nimport type {\n ListControlProps,\n ListHookProps,\n ListHookResult,\n} from \"./listTypes\";\n\nexport const useList = <Item, Selection extends SelectionStrategy = \"default\">({\n collapsibleHeaders,\n collectionHook: dataHook,\n containerRef,\n contentRef,\n defaultHighlightedIndex,\n defaultSelected,\n disabled,\n disableAriaActiveDescendant,\n disableHighlightOnFocus,\n disableTypeToSelect,\n highlightedIndex: highlightedIndexProp,\n label = \"\",\n listHandlers: listHandlersProp,\n onSelect,\n onSelectionChange,\n onHighlight,\n onKeyboardNavigation,\n onKeyDown,\n restoreLastFocus,\n selected,\n selectionStrategy,\n selectionKeys,\n stickyHeaders,\n tabToSelect,\n}: ListHookProps<Item, Selection>): ListHookResult<Item, Selection> => {\n const lastSelection = useRef<typeof selected>(selected || defaultSelected);\n const handleKeyboardNavigation = (\n evt: KeyboardEvent<HTMLElement>,\n nextIndex: number,\n ) => {\n selectionHook.listHandlers.onKeyboardNavigation?.(evt, nextIndex);\n onKeyboardNavigation?.(evt, nextIndex);\n };\n\n // TODO where do these belong ?\n const handleSelect = useCallback<SelectHandler<CollectionItem<Item>>>(\n (evt, selectedItem) => {\n if (onSelect) {\n if (isValidElement(selectedItem.value)) {\n onSelect(evt, selectedItem.label as Item);\n } else if (selectedItem.value !== null) {\n onSelect(evt, selectedItem.value);\n }\n }\n },\n [onSelect],\n );\n\n const handleSelectionChange = useCallback<\n SelectionChangeHandler<CollectionItem<Item>, Selection>\n >(\n (evt, selected) => {\n if (onSelectionChange) {\n onSelectionChange(\n evt,\n (Array.isArray(selected)\n ? selected.map((s) => (isValidElement(s.value) ? s.label : s.value))\n : selected &&\n (isValidElement(selected.value)\n ? selected.label\n : selected.value)) as Selection extends SingleSelectionStrategy\n ? Item\n : Item[],\n );\n }\n },\n [onSelectionChange],\n );\n\n const {\n highlightedIndex,\n listProps: {\n onKeyDown: navigationKeyDown,\n onMouseMove: navigationMouseMove,\n ...navigationControlProps\n },\n setHighlightedIndex,\n ...keyboardHook\n } = useKeyboardNavigation<Item, Selection>({\n containerRef,\n defaultHighlightedIndex,\n disableHighlightOnFocus,\n highlightedIndex: highlightedIndexProp,\n indexPositions: dataHook.data,\n label,\n onHighlight,\n onKeyboardNavigation: handleKeyboardNavigation,\n restoreLastFocus,\n selected: lastSelection.current,\n });\n\n const collapsibleHook = useCollapsibleGroups({\n collapsibleHeaders,\n highlightedIdx: highlightedIndex,\n collectionHook: dataHook,\n });\n\n const selectionHook = useSelection<Item, Selection>({\n defaultSelected,\n highlightedIdx: highlightedIndex,\n indexPositions: dataHook.data,\n label,\n onSelect: handleSelect,\n onSelectionChange: handleSelectionChange,\n selected,\n selectionStrategy,\n selectionKeys,\n tabToSelect,\n });\n\n const { onKeyDown: typeaheadOnKeyDown } = useTypeahead<Item>({\n disableTypeToSelect,\n highlightedIdx: highlightedIndex,\n highlightItemAtIndex: setHighlightedIndex,\n typeToNavigate: true,\n items: dataHook.data,\n });\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (!evt.defaultPrevented) {\n typeaheadOnKeyDown?.(evt);\n }\n // We still let the keyboard navigation hook process the event even\n // if it has been handled by the typeahead hook. That is so it can\n // correctly manage the focusVisible state.\n navigationKeyDown(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listHandlers.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n collapsibleHook?.onKeyDown?.(evt);\n }\n\n if (!evt.defaultPrevented) {\n onKeyDown?.(evt);\n }\n },\n [\n collapsibleHook,\n navigationKeyDown,\n onKeyDown,\n selectionHook.listHandlers,\n typeaheadOnKeyDown,\n ],\n );\n\n // This is only appropriate when we are directly controlling a List,\n // not when a control is manipulating the list\n const { isScrolling, scrollIntoView } = useViewportTracking({\n containerRef,\n contentRef,\n highlightedIdx: highlightedIndex,\n indexPositions: dataHook.data,\n stickyHeaders,\n });\n\n const handleMouseMove = useCallback(\n (evt: MouseEvent) => {\n if (!isScrolling.current && !disabled) {\n navigationMouseMove();\n const idx = closestListItemIndex(evt.target as HTMLElement);\n if (idx !== highlightedIndex) {\n const item = dataHook.data[idx];\n if (!item || item.disabled) {\n setHighlightedIndex(-1);\n } else {\n setHighlightedIndex(idx);\n }\n }\n }\n },\n [\n isScrolling,\n disabled,\n setHighlightedIndex,\n navigationMouseMove,\n highlightedIndex,\n dataHook.data,\n ],\n );\n\n const getActiveDescendant = () =>\n highlightedIndex === undefined ||\n highlightedIndex === -1 ||\n disableAriaActiveDescendant\n ? undefined\n : dataHook.data[highlightedIndex]?.id;\n\n // We need this on reEntry for navigation hook to handle focus\n lastSelection.current = selectionHook.selected;\n\n // controlProps ?\n const listControlProps: ListControlProps = {\n \"aria-activedescendant\": getActiveDescendant(),\n onBlur: navigationControlProps.onBlur,\n onFocus: navigationControlProps.onFocus,\n onKeyDown: handleKeyDown,\n onMouseDownCapture: navigationControlProps.onMouseDownCapture,\n onMouseLeave: navigationControlProps.onMouseLeave,\n };\n\n const listHandlers: ListHandlers = listHandlersProp || {\n // Don't expose a click handler when the list is disabled. Previously,\n // selection on disabled lists was prevented only as a side-effect of\n // `handleMouseMove` gating on `disabled` (which kept `highlightedIdx` at\n // -1, so `useSelection.handleClick` no-op'd). Now that `handleClick`\n // resolves the clicked item directly from the event target, we must\n // explicitly suppress the handler here.\n onClick: disabled ? undefined : selectionHook.listHandlers.onClick,\n // MouseEnter would be much better for this. There is a bug in Cypress\n // wheby it emits spurious MouseEnter (and MouseOver) events around\n // keypress events, which break many tests.\n onMouseMove: handleMouseMove,\n };\n\n return {\n focusVisible: keyboardHook.focusVisible,\n controlledHighlighting: keyboardHook.controlledHighlighting,\n highlightedIndex,\n keyboardNavigation: keyboardHook.keyboardNavigation,\n listHandlers,\n listItemHeaderHandlers: collapsibleHook,\n listControlProps,\n scrollIntoView,\n selected: selectionHook.selected,\n setHighlightedIndex,\n setIgnoreFocus: keyboardHook.setIgnoreFocus,\n setSelected: selectionHook.setSelected,\n };\n};\n"],"names":["useRef","useCallback","isValidElement","selected","useKeyboardNavigation","useCollapsibleGroups","useSelection","useTypeahead","useViewportTracking","closestListItemIndex"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { useControlled } from '@salt-ds/core';
2
2
  import { useRef, useCallback } from 'react';
3
+ import { closestListItemIndex } from './list-dom-utils.js';
3
4
 
4
5
  const defaultSelectionKeys = ["Enter", " "];
5
6
  const isSelectable = (item) => item && item.disabled !== true && item.selectable !== false;
@@ -155,19 +156,21 @@ const useSelection = ({
155
156
  );
156
157
  const handleClick = useCallback(
157
158
  (evt) => {
158
- const item = indexPositions[highlightedIdx];
159
+ const targetIdx = closestListItemIndex(evt.target);
160
+ const idx = targetIdx >= 0 ? targetIdx : highlightedIdx;
161
+ const item = indexPositions[idx];
159
162
  if (!disableSelection && isSelectable(item)) {
160
163
  evt.preventDefault();
161
164
  evt.stopPropagation();
162
165
  selectItemAtIndex(
163
166
  evt,
164
- highlightedIdx,
167
+ idx,
165
168
  item,
166
169
  evt.shiftKey,
167
170
  evt.ctrlKey || evt.metaKey
168
171
  );
169
172
  if (isExtendedSelect) {
170
- lastActive.current = highlightedIdx;
173
+ lastActive.current = idx;
171
174
  }
172
175
  }
173
176
  },
@@ -1 +1 @@
1
- {"version":3,"file":"useSelection.js","sources":["../src/common-hooks/useSelection.ts"],"sourcesContent":["import { useControlled } from \"@salt-ds/core\";\nimport {\n type KeyboardEvent,\n type MouseEvent,\n type SyntheticEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport type { CollectionItem } from \"./collectionTypes\";\nimport type {\n SelectionHookProps,\n SelectionHookResult,\n SelectionStrategy,\n SingleSelectionStrategy,\n} from \"./selectionTypes\";\n\nexport const CHECKBOX = \"checkbox\";\n\nexport const GROUP_SELECTION_NONE = \"none\";\nexport const GROUP_SELECTION_SINGLE = \"single\";\nexport const GROUP_SELECTION_CASCADE = \"cascade\";\n\nexport type GroupSelectionMode = \"none\" | \"single\" | \"cascade\";\n\nconst defaultSelectionKeys = [\"Enter\", \" \"];\n\nconst isSelectable = (item?: CollectionItem<unknown>) =>\n item && item.disabled !== true && item.selectable !== false;\n\nconst byItemIndex = (\n i1: CollectionItem<unknown>,\n i2: CollectionItem<unknown>,\n) => (i1.index ?? 0) - (i2.index ?? 0);\n\nexport const groupSelectionEnabled = (\n groupSelection: GroupSelectionMode,\n): boolean => groupSelection && groupSelection !== GROUP_SELECTION_NONE;\n\nexport const useSelection = <\n Item,\n Selection extends SelectionStrategy = \"default\",\n>({\n defaultSelected,\n disableSelection = false,\n // groupSelection = GROUP_SELECTION_NONE,\n highlightedIdx,\n indexPositions,\n label: _label = \"\",\n onSelect,\n onSelectionChange,\n selected: selectedProp,\n selectionStrategy,\n selectionKeys = defaultSelectionKeys,\n tabToSelect,\n}: SelectionHookProps<Item, Selection>): SelectionHookResult<\n Item,\n Selection\n> => {\n type collectionItem = CollectionItem<Item>;\n\n const isDeselectable = selectionStrategy === \"deselectable\";\n const isMultipleSelect = selectionStrategy === \"multiple\";\n const isExtendedSelect = selectionStrategy === \"extended\";\n\n const lastActive = useRef(-1);\n\n const isSelectionEvent = useCallback(\n (evt: KeyboardEvent) => selectionKeys.includes(evt.key),\n [selectionKeys],\n );\n\n const emptyValue = useCallback(<\n Item,\n >(): Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[] => {\n type returnType = Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[];\n return isMultipleSelect || isExtendedSelect\n ? ([] as unknown as returnType)\n : (null as returnType);\n }, [isMultipleSelect, isExtendedSelect]);\n\n const [selected, setSelected] = useControlled<\n Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[]\n >({\n controlled: selectedProp,\n default: defaultSelected ?? emptyValue(),\n name: \"UseSelection\",\n state: \"selected\",\n });\n\n const isItemSelected = useCallback(\n (item: collectionItem) => {\n return Array.isArray(selected)\n ? selected.includes(item)\n : selected === item;\n },\n [selected],\n );\n\n const selectDefault = useCallback((item: collectionItem) => item, []);\n const selectDeselectable = useCallback(\n (item: collectionItem) => (isItemSelected(item) ? null : item),\n [isItemSelected],\n );\n const selectMultiple = useCallback(\n (item: collectionItem) => {\n const nextItems = isItemSelected(item)\n ? (selected as collectionItem[]).filter((i) => i !== item)\n : (selected as collectionItem[]).concat(item);\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [isItemSelected, selected],\n );\n const selectRange = useCallback(\n (idx: number, preserveExistingSelection?: boolean) => {\n const currentSelection = preserveExistingSelection\n ? (selected as collectionItem[])\n : ([] as collectionItem[]);\n\n const [lastSelectedItem] = (selected as collectionItem[]).slice(-1);\n const lastSelectedItemIndex = lastSelectedItem\n ? indexPositions.indexOf(lastSelectedItem)\n : 0;\n\n const startRegion = Math.min(idx, lastSelectedItemIndex);\n const endRegion = Math.max(idx, lastSelectedItemIndex);\n const rangeSelection = indexPositions.slice(startRegion, endRegion + 1);\n // concat the current selection with a new selection and remove duplicates for overlaps\n const nextItems = [...new Set([...currentSelection, ...rangeSelection])];\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [indexPositions, selected],\n );\n\n const selectItemAtIndex = useCallback(\n (\n evt: SyntheticEvent,\n idx: number,\n item: collectionItem,\n rangeSelect: boolean,\n preserveExistingSelection?: boolean,\n ) => {\n type returnType = Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[];\n let newSelected: returnType;\n if (isMultipleSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (isExtendedSelect) {\n if (preserveExistingSelection && !rangeSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (rangeSelect) {\n newSelected = selectRange(\n idx,\n preserveExistingSelection,\n ) as returnType;\n } else {\n newSelected = [item] as returnType;\n }\n } else if (isDeselectable) {\n newSelected = selectDeselectable(item) as returnType;\n } else {\n newSelected = selectDefault(item) as returnType;\n }\n\n if (newSelected !== selected) {\n setSelected(newSelected);\n }\n\n // We fire onSelect irrespective of whether selection changes\n onSelect?.(evt, item);\n\n if (newSelected !== selected) {\n if (onSelectionChange) {\n onSelectionChange(evt, newSelected);\n }\n }\n },\n [\n isMultipleSelect,\n isExtendedSelect,\n isDeselectable,\n selected,\n onSelect,\n selectMultiple,\n selectRange,\n selectDeselectable,\n selectDefault,\n onSelectionChange,\n ],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n const item = indexPositions[highlightedIdx];\n if (isSelectable(item)) {\n if (isSelectionEvent(evt) || (tabToSelect && evt.key === \"Tab\")) {\n // We do not inhibit Tab behaviour, if we are selecting on Tab then we apply\n // selection as a side effect of the Tab, not as a replacement for Tabbing.\n if (evt.key !== \"Tab\") {\n evt.preventDefault();\n }\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item,\n false,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n }\n },\n [\n indexPositions,\n highlightedIdx,\n isSelectionEvent,\n tabToSelect,\n selectItemAtIndex,\n isExtendedSelect,\n ],\n );\n\n const handleKeyboardNavigation = useCallback(\n (evt: KeyboardEvent, currentIndex: number) => {\n if (isExtendedSelect && evt.shiftKey) {\n const item = indexPositions[currentIndex];\n if (isSelectable(item)) {\n selectItemAtIndex(evt, currentIndex, item, true);\n }\n }\n },\n [isExtendedSelect, indexPositions, selectItemAtIndex],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n const item = indexPositions[highlightedIdx];\n if (!disableSelection && isSelectable(item)) {\n // if (!isCollapsibleItem(item)) {\n evt.preventDefault();\n evt.stopPropagation();\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item,\n evt.shiftKey,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = highlightedIdx;\n }\n // }\n }\n },\n [\n disableSelection,\n isExtendedSelect,\n highlightedIdx,\n indexPositions,\n selectItemAtIndex,\n ],\n );\n\n const listHandlers = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onKeyboardNavigation: handleKeyboardNavigation,\n };\n\n return {\n listHandlers,\n selected,\n setSelected,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useSelection.js","sources":["../src/common-hooks/useSelection.ts"],"sourcesContent":["import { useControlled } from \"@salt-ds/core\";\nimport {\n type KeyboardEvent,\n type MouseEvent,\n type SyntheticEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport type { CollectionItem } from \"./collectionTypes\";\nimport { closestListItemIndex } from \"./list-dom-utils\";\nimport type {\n SelectionHookProps,\n SelectionHookResult,\n SelectionStrategy,\n SingleSelectionStrategy,\n} from \"./selectionTypes\";\n\nexport const CHECKBOX = \"checkbox\";\n\nexport const GROUP_SELECTION_NONE = \"none\";\nexport const GROUP_SELECTION_SINGLE = \"single\";\nexport const GROUP_SELECTION_CASCADE = \"cascade\";\n\nexport type GroupSelectionMode = \"none\" | \"single\" | \"cascade\";\n\nconst defaultSelectionKeys = [\"Enter\", \" \"];\n\nconst isSelectable = (item?: CollectionItem<unknown>) =>\n item && item.disabled !== true && item.selectable !== false;\n\nconst byItemIndex = (\n i1: CollectionItem<unknown>,\n i2: CollectionItem<unknown>,\n) => (i1.index ?? 0) - (i2.index ?? 0);\n\nexport const groupSelectionEnabled = (\n groupSelection: GroupSelectionMode,\n): boolean => groupSelection && groupSelection !== GROUP_SELECTION_NONE;\n\nexport const useSelection = <\n Item,\n Selection extends SelectionStrategy = \"default\",\n>({\n defaultSelected,\n disableSelection = false,\n // groupSelection = GROUP_SELECTION_NONE,\n highlightedIdx,\n indexPositions,\n label: _label = \"\",\n onSelect,\n onSelectionChange,\n selected: selectedProp,\n selectionStrategy,\n selectionKeys = defaultSelectionKeys,\n tabToSelect,\n}: SelectionHookProps<Item, Selection>): SelectionHookResult<\n Item,\n Selection\n> => {\n type collectionItem = CollectionItem<Item>;\n\n const isDeselectable = selectionStrategy === \"deselectable\";\n const isMultipleSelect = selectionStrategy === \"multiple\";\n const isExtendedSelect = selectionStrategy === \"extended\";\n\n const lastActive = useRef(-1);\n\n const isSelectionEvent = useCallback(\n (evt: KeyboardEvent) => selectionKeys.includes(evt.key),\n [selectionKeys],\n );\n\n const emptyValue = useCallback(<\n Item,\n >(): Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[] => {\n type returnType = Selection extends SingleSelectionStrategy\n ? null\n : CollectionItem<Item>[];\n return isMultipleSelect || isExtendedSelect\n ? ([] as unknown as returnType)\n : (null as returnType);\n }, [isMultipleSelect, isExtendedSelect]);\n\n const [selected, setSelected] = useControlled<\n Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[]\n >({\n controlled: selectedProp,\n default: defaultSelected ?? emptyValue(),\n name: \"UseSelection\",\n state: \"selected\",\n });\n\n const isItemSelected = useCallback(\n (item: collectionItem) => {\n return Array.isArray(selected)\n ? selected.includes(item)\n : selected === item;\n },\n [selected],\n );\n\n const selectDefault = useCallback((item: collectionItem) => item, []);\n const selectDeselectable = useCallback(\n (item: collectionItem) => (isItemSelected(item) ? null : item),\n [isItemSelected],\n );\n const selectMultiple = useCallback(\n (item: collectionItem) => {\n const nextItems = isItemSelected(item)\n ? (selected as collectionItem[]).filter((i) => i !== item)\n : (selected as collectionItem[]).concat(item);\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [isItemSelected, selected],\n );\n const selectRange = useCallback(\n (idx: number, preserveExistingSelection?: boolean) => {\n const currentSelection = preserveExistingSelection\n ? (selected as collectionItem[])\n : ([] as collectionItem[]);\n\n const [lastSelectedItem] = (selected as collectionItem[]).slice(-1);\n const lastSelectedItemIndex = lastSelectedItem\n ? indexPositions.indexOf(lastSelectedItem)\n : 0;\n\n const startRegion = Math.min(idx, lastSelectedItemIndex);\n const endRegion = Math.max(idx, lastSelectedItemIndex);\n const rangeSelection = indexPositions.slice(startRegion, endRegion + 1);\n // concat the current selection with a new selection and remove duplicates for overlaps\n const nextItems = [...new Set([...currentSelection, ...rangeSelection])];\n nextItems.sort(byItemIndex);\n return nextItems;\n },\n [indexPositions, selected],\n );\n\n const selectItemAtIndex = useCallback(\n (\n evt: SyntheticEvent,\n idx: number,\n item: collectionItem,\n rangeSelect: boolean,\n preserveExistingSelection?: boolean,\n ) => {\n type returnType = Selection extends SingleSelectionStrategy\n ? CollectionItem<Item> | null\n : CollectionItem<Item>[];\n let newSelected: returnType;\n if (isMultipleSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (isExtendedSelect) {\n if (preserveExistingSelection && !rangeSelect) {\n newSelected = selectMultiple(item) as returnType;\n } else if (rangeSelect) {\n newSelected = selectRange(\n idx,\n preserveExistingSelection,\n ) as returnType;\n } else {\n newSelected = [item] as returnType;\n }\n } else if (isDeselectable) {\n newSelected = selectDeselectable(item) as returnType;\n } else {\n newSelected = selectDefault(item) as returnType;\n }\n\n if (newSelected !== selected) {\n setSelected(newSelected);\n }\n\n // We fire onSelect irrespective of whether selection changes\n onSelect?.(evt, item);\n\n if (newSelected !== selected) {\n if (onSelectionChange) {\n onSelectionChange(evt, newSelected);\n }\n }\n },\n [\n isMultipleSelect,\n isExtendedSelect,\n isDeselectable,\n selected,\n onSelect,\n selectMultiple,\n selectRange,\n selectDeselectable,\n selectDefault,\n onSelectionChange,\n ],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent) => {\n const item = indexPositions[highlightedIdx];\n if (isSelectable(item)) {\n if (isSelectionEvent(evt) || (tabToSelect && evt.key === \"Tab\")) {\n // We do not inhibit Tab behaviour, if we are selecting on Tab then we apply\n // selection as a side effect of the Tab, not as a replacement for Tabbing.\n if (evt.key !== \"Tab\") {\n evt.preventDefault();\n }\n selectItemAtIndex(\n evt,\n highlightedIdx,\n item,\n false,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = highlightedIdx;\n }\n }\n }\n },\n [\n indexPositions,\n highlightedIdx,\n isSelectionEvent,\n tabToSelect,\n selectItemAtIndex,\n isExtendedSelect,\n ],\n );\n\n const handleKeyboardNavigation = useCallback(\n (evt: KeyboardEvent, currentIndex: number) => {\n if (isExtendedSelect && evt.shiftKey) {\n const item = indexPositions[currentIndex];\n if (isSelectable(item)) {\n selectItemAtIndex(evt, currentIndex, item, true);\n }\n }\n },\n [isExtendedSelect, indexPositions, selectItemAtIndex],\n );\n\n const handleClick = useCallback(\n (evt: MouseEvent) => {\n // Resolve the clicked item from the event target rather than relying on\n // `highlightedIdx`. The highlighted index is updated asynchronously from\n // a `mousemove` handler on the list; in fast/synthetic interactions\n // (notably Cypress `realClick`) the click can fire before React has\n // re-rendered with the updated highlight, which previously caused the\n // click to be silently ignored (root cause of flaky selection tests).\n const targetIdx = closestListItemIndex(evt.target as HTMLElement);\n const idx = targetIdx >= 0 ? targetIdx : highlightedIdx;\n const item = indexPositions[idx];\n if (!disableSelection && isSelectable(item)) {\n // if (!isCollapsibleItem(item)) {\n evt.preventDefault();\n evt.stopPropagation();\n selectItemAtIndex(\n evt,\n idx,\n item,\n evt.shiftKey,\n evt.ctrlKey || evt.metaKey,\n );\n if (isExtendedSelect) {\n lastActive.current = idx;\n }\n // }\n }\n },\n [\n disableSelection,\n isExtendedSelect,\n highlightedIdx,\n indexPositions,\n selectItemAtIndex,\n ],\n );\n\n const listHandlers = {\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onKeyboardNavigation: handleKeyboardNavigation,\n };\n\n return {\n listHandlers,\n selected,\n setSelected,\n };\n};\n"],"names":[],"mappings":"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"}
package/dist-es/index.js CHANGED
@@ -126,9 +126,6 @@ export { Toolbar } from './toolbar/Toolbar.js';
126
126
  export { ToolbarButton } from './toolbar/ToolbarButton.js';
127
127
  export { Tooltray } from './toolbar/Tooltray.js';
128
128
  export { ToolbarField } from './toolbar/toolbar-field/ToolbarField.js';
129
- export { ToolbarContentNext } from './toolbar-next/ToolbarContentNext.js';
130
- export { ToolbarNext } from './toolbar-next/ToolbarNext.js';
131
- export { TooltrayNext } from './toolbar-next/TooltrayNext.js';
132
129
  export { ElectronWindow } from './window/ElectronWindow.js';
133
130
  export { Window, WindowContext, isDesktop, useWindow } from './window/WindowContext.js';
134
131
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -178,7 +178,13 @@ const useList = ({
178
178
  onMouseLeave: navigationControlProps.onMouseLeave
179
179
  };
180
180
  const listHandlers = listHandlersProp || {
181
- onClick: selectionHook.listHandlers.onClick,
181
+ // Don't expose a click handler when the list is disabled. Previously,
182
+ // selection on disabled lists was prevented only as a side-effect of
183
+ // `handleMouseMove` gating on `disabled` (which kept `highlightedIdx` at
184
+ // -1, so `useSelection.handleClick` no-op'd). Now that `handleClick`
185
+ // resolves the clicked item directly from the event target, we must
186
+ // explicitly suppress the handler here.
187
+ onClick: disabled ? void 0 : selectionHook.listHandlers.onClick,
182
188
  // MouseEnter would be much better for this. There is a bug in Cypress
183
189
  // wheby it emits spurious MouseEnter (and MouseOver) events around
184
190
  // keypress events, which break many tests.