@fluentui/react-combobox 9.0.0-beta.8 → 9.0.0-beta.9

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 (84) hide show
  1. package/CHANGELOG.json +117 -4
  2. package/CHANGELOG.md +28 -5
  3. package/Spec.md +4 -4
  4. package/dist/index.d.ts +25 -16
  5. package/lib/components/Combobox/Combobox.types.js.map +1 -1
  6. package/lib/components/Combobox/renderCombobox.js +3 -4
  7. package/lib/components/Combobox/renderCombobox.js.map +1 -1
  8. package/lib/components/Combobox/useCombobox.js +153 -15
  9. package/lib/components/Combobox/useCombobox.js.map +1 -1
  10. package/lib/components/Combobox/useComboboxStyles.js +56 -25
  11. package/lib/components/Combobox/useComboboxStyles.js.map +1 -1
  12. package/lib/components/Dropdown/Dropdown.types.js.map +1 -1
  13. package/lib/components/Dropdown/renderDropdown.js +3 -4
  14. package/lib/components/Dropdown/renderDropdown.js.map +1 -1
  15. package/lib/components/Dropdown/useDropdown.js +100 -8
  16. package/lib/components/Dropdown/useDropdown.js.map +1 -1
  17. package/lib/components/Dropdown/useDropdownStyles.js +41 -19
  18. package/lib/components/Dropdown/useDropdownStyles.js.map +1 -1
  19. package/lib/components/Listbox/Listbox.types.js.map +1 -1
  20. package/lib/components/Listbox/useListbox.js +25 -17
  21. package/lib/components/Listbox/useListbox.js.map +1 -1
  22. package/lib/components/Option/Option.types.js.map +1 -1
  23. package/lib/components/Option/useOption.js +29 -21
  24. package/lib/components/Option/useOption.js.map +1 -1
  25. package/lib/components/Option/useOptionStyles.js +2 -1
  26. package/lib/components/Option/useOptionStyles.js.map +1 -1
  27. package/lib/contexts/ComboboxContext.js +11 -4
  28. package/lib/contexts/ComboboxContext.js.map +1 -1
  29. package/lib/contexts/ListboxContext.js +9 -4
  30. package/lib/contexts/ListboxContext.js.map +1 -1
  31. package/lib/contexts/useComboboxContextValues.js +8 -2
  32. package/lib/contexts/useComboboxContextValues.js.map +1 -1
  33. package/lib/contexts/useListboxContextValues.js +8 -4
  34. package/lib/contexts/useListboxContextValues.js.map +1 -1
  35. package/lib/utils/ComboboxBase.types.js.map +1 -1
  36. package/lib/utils/Selection.types.js.map +1 -1
  37. package/lib/utils/dropdownKeyActions.js +2 -9
  38. package/lib/utils/dropdownKeyActions.js.map +1 -1
  39. package/lib/utils/useComboboxBaseState.js +29 -24
  40. package/lib/utils/useComboboxBaseState.js.map +1 -1
  41. package/lib/utils/useComboboxPopup.js +5 -3
  42. package/lib/utils/useComboboxPopup.js.map +1 -1
  43. package/lib/utils/useSelection.js +13 -4
  44. package/lib/utils/useSelection.js.map +1 -1
  45. package/lib/utils/useTriggerListboxSlots.js +45 -50
  46. package/lib/utils/useTriggerListboxSlots.js.map +1 -1
  47. package/lib-commonjs/components/Combobox/renderCombobox.js +3 -4
  48. package/lib-commonjs/components/Combobox/renderCombobox.js.map +1 -1
  49. package/lib-commonjs/components/Combobox/useCombobox.js +152 -14
  50. package/lib-commonjs/components/Combobox/useCombobox.js.map +1 -1
  51. package/lib-commonjs/components/Combobox/useComboboxStyles.js +56 -25
  52. package/lib-commonjs/components/Combobox/useComboboxStyles.js.map +1 -1
  53. package/lib-commonjs/components/Dropdown/renderDropdown.js +3 -4
  54. package/lib-commonjs/components/Dropdown/renderDropdown.js.map +1 -1
  55. package/lib-commonjs/components/Dropdown/useDropdown.js +101 -7
  56. package/lib-commonjs/components/Dropdown/useDropdown.js.map +1 -1
  57. package/lib-commonjs/components/Dropdown/useDropdownStyles.js +41 -19
  58. package/lib-commonjs/components/Dropdown/useDropdownStyles.js.map +1 -1
  59. package/lib-commonjs/components/Listbox/useListbox.js +24 -16
  60. package/lib-commonjs/components/Listbox/useListbox.js.map +1 -1
  61. package/lib-commonjs/components/Option/useOption.js +29 -21
  62. package/lib-commonjs/components/Option/useOption.js.map +1 -1
  63. package/lib-commonjs/components/Option/useOptionStyles.js +2 -1
  64. package/lib-commonjs/components/Option/useOptionStyles.js.map +1 -1
  65. package/lib-commonjs/contexts/ComboboxContext.js +11 -4
  66. package/lib-commonjs/contexts/ComboboxContext.js.map +1 -1
  67. package/lib-commonjs/contexts/ListboxContext.js +9 -4
  68. package/lib-commonjs/contexts/ListboxContext.js.map +1 -1
  69. package/lib-commonjs/contexts/useComboboxContextValues.js +8 -2
  70. package/lib-commonjs/contexts/useComboboxContextValues.js.map +1 -1
  71. package/lib-commonjs/contexts/useListboxContextValues.js +8 -4
  72. package/lib-commonjs/contexts/useListboxContextValues.js.map +1 -1
  73. package/lib-commonjs/utils/dropdownKeyActions.js +2 -9
  74. package/lib-commonjs/utils/dropdownKeyActions.js.map +1 -1
  75. package/lib-commonjs/utils/useComboboxBaseState.js +29 -24
  76. package/lib-commonjs/utils/useComboboxBaseState.js.map +1 -1
  77. package/lib-commonjs/utils/useComboboxPopup.js +5 -3
  78. package/lib-commonjs/utils/useComboboxPopup.js.map +1 -1
  79. package/lib-commonjs/utils/useSelection.js +13 -4
  80. package/lib-commonjs/utils/useSelection.js.map +1 -1
  81. package/lib-commonjs/utils/useTriggerListboxSlots.js +44 -49
  82. package/lib-commonjs/utils/useTriggerListboxSlots.js.map +1 -1
  83. package/package.json +9 -9
  84. package/dist/tsdoc-metadata.json +0 -11
@@ -26,16 +26,18 @@ function useTriggerListboxSlots(props, state, ref, triggerSlot, listboxSlot) {
26
26
  getCount,
27
27
  getIndexOfId,
28
28
  getOptionAtIndex,
29
+ ignoreNextBlur,
29
30
  open,
30
31
  selectOption,
31
32
  setActiveOption,
33
+ setFocusVisible,
34
+ setHasFocus,
32
35
  setOpen
33
36
  } = state; // handle trigger focus/blur
34
37
 
35
- const triggerRef = React.useRef(null);
36
- const ignoreTriggerBlur = React.useRef(false); // resolve listbox shorthand props
38
+ const triggerRef = React.useRef(null); // resolve listbox shorthand props
37
39
 
38
- const listbox = {
40
+ const listbox = listboxSlot && {
39
41
  multiselect,
40
42
  tabIndex: undefined,
41
43
  ...listboxSlot
@@ -50,53 +52,44 @@ function useTriggerListboxSlots(props, state, ref, triggerSlot, listboxSlot) {
50
52
  // since the `children` prop has mutually incompatible types between input/button
51
53
  // functionally both ref and triggerRef will always be the same element type
52
54
  ref: react_utilities_1.useMergedRefs(ref, triggerSlot === null || triggerSlot === void 0 ? void 0 : triggerSlot.ref, triggerRef)
53
- };
54
- /*
55
- * Handle focus when clicking the listbox popup:
56
- * 1. Move focus back to the button/input when the listbox is clicked (otherwise it goes to body)
57
- * 2. Do not close the listbox on button/input blur when clicking into the listbox
58
- */
59
-
60
- const {
61
- onClick: onListboxClick,
62
- onMouseDown: onListboxMouseDown
63
- } = listbox;
64
-
65
- listbox.onClick = event => {
66
- var _a;
67
-
68
- (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
69
- onListboxClick === null || onListboxClick === void 0 ? void 0 : onListboxClick(event);
70
- };
71
-
72
- listbox.onMouseDown = event => {
73
- ignoreTriggerBlur.current = true;
74
- onListboxMouseDown === null || onListboxMouseDown === void 0 ? void 0 : onListboxMouseDown(event);
75
- }; // the trigger should open/close the popup on click or blur
76
-
77
-
78
- const {
79
- onBlur: onTriggerBlur,
80
- onClick: onTriggerClick,
81
- onKeyDown: onTriggerKeyDown
82
- } = trigger;
83
-
84
- trigger.onBlur = event => {
85
- if (!ignoreTriggerBlur.current) {
55
+ }; // listbox is nullable, only add event handlers if it exists
56
+
57
+ if (listbox) {
58
+ /*
59
+ * Handle focus when clicking the listbox popup:
60
+ * 1. Move focus back to the button/input when the listbox is clicked (otherwise it goes to body)
61
+ * 2. Do not close the listbox on button/input blur when clicking into the listbox
62
+ */
63
+ listbox.onClick = react_utilities_1.mergeCallbacks(event => {
64
+ var _a;
65
+
66
+ (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
67
+ }, listbox.onClick);
68
+ listbox.onMouseOver = react_utilities_1.mergeCallbacks(event => {
69
+ setFocusVisible(false);
70
+ }, listbox.onMouseOver);
71
+ listbox.onMouseDown = react_utilities_1.mergeCallbacks(event => {
72
+ ignoreNextBlur.current = true;
73
+ }, listbox.onMouseDown);
74
+ } // the trigger should open/close the popup on click or blur
75
+
76
+
77
+ trigger.onBlur = react_utilities_1.mergeCallbacks(event => {
78
+ if (!ignoreNextBlur.current) {
86
79
  setOpen(event, false);
87
80
  }
88
81
 
89
- ignoreTriggerBlur.current = false;
90
- onTriggerBlur === null || onTriggerBlur === void 0 ? void 0 : onTriggerBlur(event);
91
- };
92
-
93
- trigger.onClick = event => {
82
+ ignoreNextBlur.current = false;
83
+ setHasFocus(false);
84
+ }, trigger.onBlur);
85
+ trigger.onClick = react_utilities_1.mergeCallbacks(event => {
94
86
  setOpen(event, !open);
95
- onTriggerClick === null || onTriggerClick === void 0 ? void 0 : onTriggerClick(event);
96
- }; // handle combobox keyboard interaction
87
+ }, trigger.onClick);
88
+ trigger.onFocus = react_utilities_1.mergeCallbacks(event => {
89
+ setHasFocus(true);
90
+ }, trigger.onFocus); // handle combobox keyboard interaction
97
91
 
98
-
99
- trigger.onKeyDown = event => {
92
+ trigger.onKeyDown = react_utilities_1.mergeCallbacks(event => {
100
93
  const action = dropdownKeyActions_1.getDropdownActionFromKey(event, {
101
94
  open,
102
95
  multiselect
@@ -108,6 +101,7 @@ function useTriggerListboxSlots(props, state, ref, triggerSlot, listboxSlot) {
108
101
  switch (action) {
109
102
  case 'Open':
110
103
  event.preventDefault();
104
+ setFocusVisible(true);
111
105
  setOpen(event, true);
112
106
  break;
113
107
 
@@ -139,11 +133,12 @@ function useTriggerListboxSlots(props, state, ref, triggerSlot, listboxSlot) {
139
133
  // prevent default page scroll/keyboard action if the index changed
140
134
  event.preventDefault();
141
135
  setActiveOption(getOptionAtIndex(newIndex));
136
+ setFocusVisible(true);
142
137
  }
143
-
144
- onTriggerKeyDown === null || onTriggerKeyDown === void 0 ? void 0 : onTriggerKeyDown(event);
145
- };
146
-
138
+ }, trigger.onKeyDown);
139
+ trigger.onMouseOver = react_utilities_1.mergeCallbacks(event => {
140
+ setFocusVisible(false);
141
+ }, trigger.onMouseOver);
147
142
  return [trigger, listbox];
148
143
  }
149
144
 
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/useTriggerListboxSlots.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { useMergedRefs } from '@fluentui/react-utilities';\nimport type { ExtractSlotProps, Slot } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey, getIndexFromAction } from '../utils/dropdownKeyActions';\nimport { Listbox } from '../components/Listbox/Listbox';\nimport type { ComboboxBaseProps, ComboboxBaseState } from './ComboboxBase.types';\n\nexport function useTriggerListboxSlots(\n props: ComboboxBaseProps,\n state: ComboboxBaseState,\n ref: React.Ref<HTMLButtonElement>,\n triggerSlot?: ExtractSlotProps<Slot<'button'>>,\n listboxSlot?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [ExtractSlotProps<Slot<'button'>>, ExtractSlotProps<Slot<typeof Listbox>>];\nexport function useTriggerListboxSlots(\n props: ComboboxBaseProps,\n state: ComboboxBaseState,\n ref: React.Ref<HTMLInputElement>,\n triggerSlot?: ExtractSlotProps<Slot<'input'>>,\n listboxSlot?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [ExtractSlotProps<Slot<'input'>>, ExtractSlotProps<Slot<typeof Listbox>>];\n\n/*\n * useTriggerListboxSlots returns a tuple of trigger/listbox shorthand,\n * with the semantics and event handlers needed for the Combobox and Dropdown components.\n * The element type of the ref should always match the element type used in the trigger shorthand.\n */\nexport function useTriggerListboxSlots(\n props: ComboboxBaseProps,\n state: ComboboxBaseState,\n ref: React.Ref<HTMLButtonElement | HTMLInputElement>,\n triggerSlot?: ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>,\n listboxSlot?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>, ExtractSlotProps<Slot<typeof Listbox>>] {\n const { multiselect } = props;\n const {\n activeOption,\n getCount,\n getIndexOfId,\n getOptionAtIndex,\n open,\n selectOption,\n setActiveOption,\n setOpen,\n } = state;\n\n // handle trigger focus/blur\n const triggerRef: typeof ref = React.useRef(null);\n const ignoreTriggerBlur = React.useRef(false);\n\n // resolve listbox shorthand props\n const listbox: typeof listboxSlot = {\n multiselect,\n tabIndex: undefined,\n ...listboxSlot,\n };\n\n // resolve trigger shorthand props\n const trigger: typeof triggerSlot = {\n 'aria-expanded': open,\n 'aria-activedescendant': open ? activeOption?.id : undefined,\n role: 'combobox',\n ...triggerSlot,\n // explicitly type the ref as an intersection here to prevent type errors\n // since the `children` prop has mutually incompatible types between input/button\n // functionally both ref and triggerRef will always be the same element type\n ref: useMergedRefs(ref, triggerSlot?.ref, triggerRef) as React.Ref<HTMLButtonElement & HTMLInputElement>,\n };\n\n /*\n * Handle focus when clicking the listbox popup:\n * 1. Move focus back to the button/input when the listbox is clicked (otherwise it goes to body)\n * 2. Do not close the listbox on button/input blur when clicking into the listbox\n */\n const { onClick: onListboxClick, onMouseDown: onListboxMouseDown } = listbox;\n listbox.onClick = (event: React.MouseEvent<HTMLDivElement>) => {\n triggerRef.current?.focus();\n\n onListboxClick?.(event);\n };\n\n listbox.onMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n ignoreTriggerBlur.current = true;\n\n onListboxMouseDown?.(event);\n };\n\n // the trigger should open/close the popup on click or blur\n const { onBlur: onTriggerBlur, onClick: onTriggerClick, onKeyDown: onTriggerKeyDown } = trigger;\n trigger.onBlur = (event: React.FocusEvent<HTMLButtonElement> & React.FocusEvent<HTMLInputElement>) => {\n if (!ignoreTriggerBlur.current) {\n setOpen(event, false);\n }\n\n ignoreTriggerBlur.current = false;\n\n onTriggerBlur?.(event);\n };\n\n trigger.onClick = (event: React.MouseEvent<HTMLButtonElement> & React.MouseEvent<HTMLInputElement>) => {\n setOpen(event, !open);\n\n onTriggerClick?.(event);\n };\n\n // handle combobox keyboard interaction\n trigger.onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement> & React.KeyboardEvent<HTMLInputElement>) => {\n const action = getDropdownActionFromKey(event, { open, multiselect });\n const maxIndex = getCount() - 1;\n const activeIndex = activeOption ? getIndexOfId(activeOption.id) : -1;\n let newIndex = activeIndex;\n\n switch (action) {\n case 'Open':\n event.preventDefault();\n setOpen(event, true);\n break;\n case 'Close':\n // stop propagation for escape key to avoid dismissing any parent popups\n event.stopPropagation();\n event.preventDefault();\n setOpen(event, false);\n break;\n case 'CloseSelect':\n !multiselect && !activeOption?.disabled && setOpen(event, false);\n // fallthrough\n case 'Select':\n activeOption && selectOption(event, activeOption);\n event.preventDefault();\n break;\n case 'Tab':\n activeOption && selectOption(event, activeOption);\n break;\n default:\n newIndex = getIndexFromAction(action, activeIndex, maxIndex);\n }\n if (newIndex !== activeIndex) {\n // prevent default page scroll/keyboard action if the index changed\n event.preventDefault();\n setActiveOption(getOptionAtIndex(newIndex));\n }\n\n onTriggerKeyDown?.(event);\n };\n\n return [trigger, listbox];\n}\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/useTriggerListboxSlots.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { mergeCallbacks, useMergedRefs } from '@fluentui/react-utilities';\nimport type { ExtractSlotProps, Slot } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey, getIndexFromAction } from '../utils/dropdownKeyActions';\nimport { Listbox } from '../components/Listbox/Listbox';\nimport type { ComboboxBaseProps, ComboboxBaseState } from './ComboboxBase.types';\n\nexport function useTriggerListboxSlots(\n props: ComboboxBaseProps,\n state: ComboboxBaseState,\n ref: React.Ref<HTMLButtonElement>,\n triggerSlot?: ExtractSlotProps<Slot<'button'>>,\n listboxSlot?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [trigger: ExtractSlotProps<Slot<'button'>>, listbox?: ExtractSlotProps<Slot<typeof Listbox>>];\nexport function useTriggerListboxSlots(\n props: ComboboxBaseProps,\n state: ComboboxBaseState,\n ref: React.Ref<HTMLInputElement>,\n triggerSlot?: ExtractSlotProps<Slot<'input'>>,\n listboxSlot?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [trigger: ExtractSlotProps<Slot<'input'>>, listbox?: ExtractSlotProps<Slot<typeof Listbox>>];\n\n/*\n * useTriggerListboxSlots returns a tuple of trigger/listbox shorthand,\n * with the semantics and event handlers needed for the Combobox and Dropdown components.\n * The element type of the ref should always match the element type used in the trigger shorthand.\n */\nexport function useTriggerListboxSlots(\n props: ComboboxBaseProps,\n state: ComboboxBaseState,\n ref: React.Ref<HTMLButtonElement | HTMLInputElement>,\n triggerSlot?: ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>,\n listboxSlot?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [\n trigger: ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>,\n listbox?: ExtractSlotProps<Slot<typeof Listbox>>,\n] {\n const { multiselect } = props;\n const {\n activeOption,\n getCount,\n getIndexOfId,\n getOptionAtIndex,\n ignoreNextBlur,\n open,\n selectOption,\n setActiveOption,\n setFocusVisible,\n setHasFocus,\n setOpen,\n } = state;\n\n // handle trigger focus/blur\n const triggerRef: typeof ref = React.useRef(null);\n\n // resolve listbox shorthand props\n const listbox: typeof listboxSlot = listboxSlot && {\n multiselect,\n tabIndex: undefined,\n ...listboxSlot,\n };\n\n // resolve trigger shorthand props\n const trigger: typeof triggerSlot = {\n 'aria-expanded': open,\n 'aria-activedescendant': open ? activeOption?.id : undefined,\n role: 'combobox',\n ...triggerSlot,\n // explicitly type the ref as an intersection here to prevent type errors\n // since the `children` prop has mutually incompatible types between input/button\n // functionally both ref and triggerRef will always be the same element type\n ref: useMergedRefs(ref, triggerSlot?.ref, triggerRef) as React.Ref<HTMLButtonElement & HTMLInputElement>,\n };\n\n // listbox is nullable, only add event handlers if it exists\n if (listbox) {\n /*\n * Handle focus when clicking the listbox popup:\n * 1. Move focus back to the button/input when the listbox is clicked (otherwise it goes to body)\n * 2. Do not close the listbox on button/input blur when clicking into the listbox\n */\n listbox.onClick = mergeCallbacks((event: React.MouseEvent<HTMLDivElement>) => {\n triggerRef.current?.focus();\n }, listbox.onClick);\n\n listbox.onMouseOver = mergeCallbacks((event: React.MouseEvent<HTMLDivElement>) => {\n setFocusVisible(false);\n }, listbox.onMouseOver);\n\n listbox.onMouseDown = mergeCallbacks((event: React.MouseEvent<HTMLDivElement>) => {\n ignoreNextBlur.current = true;\n }, listbox.onMouseDown);\n }\n\n // the trigger should open/close the popup on click or blur\n trigger.onBlur = mergeCallbacks((event: React.FocusEvent<HTMLButtonElement> & React.FocusEvent<HTMLInputElement>) => {\n if (!ignoreNextBlur.current) {\n setOpen(event, false);\n }\n\n ignoreNextBlur.current = false;\n\n setHasFocus(false);\n }, trigger.onBlur);\n\n trigger.onClick = mergeCallbacks(\n (event: React.MouseEvent<HTMLButtonElement> & React.MouseEvent<HTMLInputElement>) => {\n setOpen(event, !open);\n },\n trigger.onClick,\n );\n\n trigger.onFocus = mergeCallbacks(\n (event: React.FocusEvent<HTMLButtonElement> & React.FocusEvent<HTMLInputElement>) => {\n setHasFocus(true);\n },\n trigger.onFocus,\n );\n\n // handle combobox keyboard interaction\n trigger.onKeyDown = mergeCallbacks(\n (event: React.KeyboardEvent<HTMLButtonElement> & React.KeyboardEvent<HTMLInputElement>) => {\n const action = getDropdownActionFromKey(event, { open, multiselect });\n const maxIndex = getCount() - 1;\n const activeIndex = activeOption ? getIndexOfId(activeOption.id) : -1;\n let newIndex = activeIndex;\n\n switch (action) {\n case 'Open':\n event.preventDefault();\n setFocusVisible(true);\n setOpen(event, true);\n break;\n case 'Close':\n // stop propagation for escape key to avoid dismissing any parent popups\n event.stopPropagation();\n event.preventDefault();\n setOpen(event, false);\n break;\n case 'CloseSelect':\n !multiselect && !activeOption?.disabled && setOpen(event, false);\n // fallthrough\n case 'Select':\n activeOption && selectOption(event, activeOption);\n event.preventDefault();\n break;\n case 'Tab':\n activeOption && selectOption(event, activeOption);\n break;\n default:\n newIndex = getIndexFromAction(action, activeIndex, maxIndex);\n }\n if (newIndex !== activeIndex) {\n // prevent default page scroll/keyboard action if the index changed\n event.preventDefault();\n setActiveOption(getOptionAtIndex(newIndex));\n setFocusVisible(true);\n }\n },\n trigger.onKeyDown,\n );\n\n trigger.onMouseOver = mergeCallbacks(\n (event: React.MouseEvent<HTMLButtonElement> & React.MouseEvent<HTMLInputElement>) => {\n setFocusVisible(false);\n },\n trigger.onMouseOver,\n );\n\n return [trigger, listbox];\n}\n"],"sourceRoot":"../src/"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-combobox",
3
- "version": "9.0.0-beta.8",
3
+ "version": "9.0.0-beta.9",
4
4
  "description": "Fluent UI React Combobox component",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -22,24 +22,24 @@
22
22
  "test": "jest --passWithNoTests",
23
23
  "docs": "api-extractor run --config=config/api-extractor.local.json --local",
24
24
  "build:local": "tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/types/packages/react-components/react-combobox/src && yarn docs",
25
- "storybook": "node ../../../scripts/storybook/runner",
25
+ "storybook": "start-storybook",
26
26
  "type-check": "tsc -b tsconfig.json"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@fluentui/eslint-plugin": "*",
30
30
  "@fluentui/react-conformance": "*",
31
- "@fluentui/react-conformance-griffel": "9.0.0-beta.12",
31
+ "@fluentui/react-conformance-griffel": "9.0.0-beta.13",
32
32
  "@fluentui/scripts": "^1.0.0"
33
33
  },
34
34
  "dependencies": {
35
35
  "@fluentui/keyboard-keys": "^9.0.0",
36
- "@fluentui/react-context-selector": "^9.0.2",
36
+ "@fluentui/react-context-selector": "^9.0.3",
37
37
  "@fluentui/react-icons": "^2.0.175",
38
- "@fluentui/react-portal": "^9.0.4",
39
- "@fluentui/react-positioning": "^9.1.2",
40
- "@fluentui/react-theme": "^9.0.0",
41
- "@fluentui/react-utilities": "^9.0.2",
42
- "@griffel/react": "^1.2.3",
38
+ "@fluentui/react-portal": "^9.0.5",
39
+ "@fluentui/react-positioning": "^9.2.0",
40
+ "@fluentui/react-theme": "^9.1.0",
41
+ "@fluentui/react-utilities": "^9.1.0",
42
+ "@griffel/react": "^1.3.0",
43
43
  "tslib": "^2.1.0"
44
44
  },
45
45
  "peerDependencies": {
@@ -1,11 +0,0 @@
1
- // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
- // It should be published with your NPM package. It should not be tracked by Git.
3
- {
4
- "tsdocVersion": "0.12",
5
- "toolPackages": [
6
- {
7
- "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.18.1"
9
- }
10
- ]
11
- }