@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
@@ -13,8 +13,9 @@ const react_context_selector_1 = /*#__PURE__*/require("@fluentui/react-context-s
13
13
 
14
14
  const react_icons_1 = /*#__PURE__*/require("@fluentui/react-icons");
15
15
 
16
- const ListboxContext_1 = /*#__PURE__*/require("../../contexts/ListboxContext"); // TODO: refine this more
16
+ const ComboboxContext_1 = /*#__PURE__*/require("../../contexts/ComboboxContext");
17
17
 
18
+ const ListboxContext_1 = /*#__PURE__*/require("../../contexts/ListboxContext");
18
19
 
19
20
  function getValueString(value, children) {
20
21
  if (value) {
@@ -46,20 +47,26 @@ const useOption_unstable = (props, ref) => {
46
47
  value
47
48
  } = props;
48
49
  const optionRef = React.useRef(null);
49
- const optionValue = getValueString(value, props.children); // context values
50
+ const optionValue = getValueString(value, props.children); // use the id if provided, otherwise use a generated id
50
51
 
52
+ const id = react_utilities_1.useId('fluent-option', props.id); // data used for context registration & events
53
+
54
+ const optionData = React.useMemo(() => ({
55
+ id,
56
+ disabled,
57
+ value: optionValue
58
+ }), [id, disabled, optionValue]); // context values
59
+
60
+ const focusVisible = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => ctx.focusVisible);
51
61
  const multiselect = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => ctx.multiselect);
52
- const onOptionClick = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => ctx.onOptionClick);
53
62
  const registerOption = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => ctx.registerOption);
54
63
  const selected = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => {
55
64
  const selectedOptions = ctx.selectedOptions;
56
65
  return !!optionValue && !!selectedOptions.find(o => o === optionValue);
57
- }); // use the id if provided, otherwise use a generated id
58
-
59
- const defaultId = react_utilities_1.useId('fluent-option');
60
- const id = React.useMemo(() => {
61
- return props.id || defaultId;
62
- }, [props.id, defaultId]); // current active option?
66
+ });
67
+ const selectOption = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => ctx.selectOption);
68
+ const setActiveOption = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => ctx.setActiveOption);
69
+ const setOpen = react_context_selector_1.useContextSelector(ComboboxContext_1.ComboboxContext, ctx => ctx.setOpen); // current active option?
63
70
 
64
71
  const active = react_context_selector_1.useContextSelector(ListboxContext_1.ListboxContext, ctx => {
65
72
  var _a, _b;
@@ -79,26 +86,26 @@ const useOption_unstable = (props, ref) => {
79
86
  if (disabled) {
80
87
  event.preventDefault();
81
88
  return;
82
- }
89
+ } // clicked option should always become active option
83
90
 
84
- onOptionClick(event, {
85
- id,
86
- disabled,
87
- value: optionValue
88
- });
91
+
92
+ setActiveOption(optionData); // close on option click for single-select options in a combobox
93
+
94
+ if (!multiselect) {
95
+ setOpen === null || setOpen === void 0 ? void 0 : setOpen(event, false);
96
+ } // handle selection change
97
+
98
+
99
+ selectOption(event, optionData);
89
100
  (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event);
90
101
  }; // register option data with context
91
102
 
92
103
 
93
104
  React.useEffect(() => {
94
105
  if (id && optionRef.current) {
95
- return registerOption({
96
- id,
97
- disabled,
98
- value: optionValue
99
- }, optionRef.current);
106
+ return registerOption(optionData, optionRef.current);
100
107
  }
101
- }, [registerOption, id, disabled, optionValue]);
108
+ }, [id, optionData, registerOption]);
102
109
  return {
103
110
  components: {
104
111
  root: 'div',
@@ -122,6 +129,7 @@ const useOption_unstable = (props, ref) => {
122
129
  }),
123
130
  active,
124
131
  disabled,
132
+ focusVisible,
125
133
  multiselect,
126
134
  selected
127
135
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["components/Option/useOption.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { getNativeElementProps, resolveShorthand, useId, useMergedRefs } from '@fluentui/react-utilities';\nimport { useContextSelector } from '@fluentui/react-context-selector';\nimport { CheckmarkFilled, CheckboxUncheckedFilled, CheckboxCheckedFilled } from '@fluentui/react-icons';\nimport { ListboxContext } from '../../contexts/ListboxContext';\nimport type { OptionProps, OptionState } from './Option.types';\n\n// TODO: refine this more\nfunction getValueString(value: string | undefined, children: React.ReactNode) {\n if (value) {\n return value;\n }\n\n let valueString = '';\n React.Children.forEach(children, child => {\n if (typeof child === 'string') {\n valueString += child;\n }\n });\n return valueString;\n}\n\n/**\n * Create the state required to render Option.\n *\n * The returned state can be modified with hooks such as useOptionStyles_unstable,\n * before being passed to renderOption_unstable.\n *\n * @param props - props from this instance of Option\n * @param ref - reference to root HTMLElement of Option\n */\nexport const useOption_unstable = (props: OptionProps, ref: React.Ref<HTMLElement>): OptionState => {\n const { disabled, value } = props;\n const optionRef = React.useRef<HTMLElement>(null);\n const optionValue = getValueString(value, props.children);\n\n // context values\n const multiselect = useContextSelector(ListboxContext, ctx => ctx.multiselect);\n const onOptionClick = useContextSelector(ListboxContext, ctx => ctx.onOptionClick);\n const registerOption = useContextSelector(ListboxContext, ctx => ctx.registerOption);\n const selected = useContextSelector(ListboxContext, ctx => {\n const selectedOptions = ctx.selectedOptions;\n\n return !!optionValue && !!selectedOptions.find(o => o === optionValue);\n });\n\n // use the id if provided, otherwise use a generated id\n const defaultId = useId('fluent-option');\n const id = React.useMemo(() => {\n return props.id || defaultId;\n }, [props.id, defaultId]);\n\n // current active option?\n const active = useContextSelector(ListboxContext, ctx => {\n return ctx.activeOption?.id !== undefined && ctx.activeOption?.id === id;\n });\n\n // check icon\n let CheckIcon = <CheckmarkFilled />;\n if (multiselect) {\n CheckIcon = selected ? <CheckboxCheckedFilled /> : <CheckboxUncheckedFilled />;\n }\n\n const onClick = (event: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n onOptionClick(event, { id, disabled, value: optionValue });\n props.onClick?.(event);\n };\n\n // register option data with context\n React.useEffect(() => {\n if (id && optionRef.current) {\n return registerOption({ id, disabled, value: optionValue }, optionRef.current);\n }\n }, [registerOption, id, disabled, optionValue]);\n\n return {\n components: {\n root: 'div',\n checkIcon: 'span',\n },\n root: getNativeElementProps('div', {\n ref: useMergedRefs(ref, optionRef),\n role: 'option',\n 'aria-disabled': disabled ? 'true' : undefined,\n 'aria-selected': `${selected}`,\n id,\n ...props,\n onClick,\n }),\n checkIcon: resolveShorthand(props.checkIcon, {\n required: true,\n defaultProps: {\n 'aria-hidden': 'true',\n children: CheckIcon,\n },\n }),\n active,\n disabled,\n multiselect,\n selected,\n };\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/Option/useOption.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { getNativeElementProps, resolveShorthand, useId, useMergedRefs } from '@fluentui/react-utilities';\nimport { useContextSelector } from '@fluentui/react-context-selector';\nimport { CheckmarkFilled, CheckboxUncheckedFilled, CheckboxCheckedFilled } from '@fluentui/react-icons';\nimport { ComboboxContext } from '../../contexts/ComboboxContext';\nimport { ListboxContext } from '../../contexts/ListboxContext';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { OptionProps, OptionState } from './Option.types';\n\nfunction getValueString(value: string | undefined, children: React.ReactNode) {\n if (value) {\n return value;\n }\n\n let valueString = '';\n React.Children.forEach(children, child => {\n if (typeof child === 'string') {\n valueString += child;\n }\n });\n return valueString;\n}\n\n/**\n * Create the state required to render Option.\n *\n * The returned state can be modified with hooks such as useOptionStyles_unstable,\n * before being passed to renderOption_unstable.\n *\n * @param props - props from this instance of Option\n * @param ref - reference to root HTMLElement of Option\n */\nexport const useOption_unstable = (props: OptionProps, ref: React.Ref<HTMLElement>): OptionState => {\n const { disabled, value } = props;\n const optionRef = React.useRef<HTMLElement>(null);\n const optionValue = getValueString(value, props.children);\n\n // use the id if provided, otherwise use a generated id\n const id = useId('fluent-option', props.id);\n\n // data used for context registration & events\n const optionData = React.useMemo<OptionValue>(() => ({ id, disabled, value: optionValue }), [\n id,\n disabled,\n optionValue,\n ]);\n\n // context values\n const focusVisible = useContextSelector(ListboxContext, ctx => ctx.focusVisible);\n const multiselect = useContextSelector(ListboxContext, ctx => ctx.multiselect);\n const registerOption = useContextSelector(ListboxContext, ctx => ctx.registerOption);\n const selected = useContextSelector(ListboxContext, ctx => {\n const selectedOptions = ctx.selectedOptions;\n\n return !!optionValue && !!selectedOptions.find(o => o === optionValue);\n });\n const selectOption = useContextSelector(ListboxContext, ctx => ctx.selectOption);\n const setActiveOption = useContextSelector(ListboxContext, ctx => ctx.setActiveOption);\n const setOpen = useContextSelector(ComboboxContext, ctx => ctx.setOpen);\n\n // current active option?\n const active = useContextSelector(ListboxContext, ctx => {\n return ctx.activeOption?.id !== undefined && ctx.activeOption?.id === id;\n });\n\n // check icon\n let CheckIcon = <CheckmarkFilled />;\n if (multiselect) {\n CheckIcon = selected ? <CheckboxCheckedFilled /> : <CheckboxUncheckedFilled />;\n }\n\n const onClick = (event: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n // clicked option should always become active option\n setActiveOption(optionData);\n\n // close on option click for single-select options in a combobox\n if (!multiselect) {\n setOpen?.(event, false);\n }\n\n // handle selection change\n selectOption(event, optionData);\n\n props.onClick?.(event);\n };\n\n // register option data with context\n React.useEffect(() => {\n if (id && optionRef.current) {\n return registerOption(optionData, optionRef.current);\n }\n }, [id, optionData, registerOption]);\n\n return {\n components: {\n root: 'div',\n checkIcon: 'span',\n },\n root: getNativeElementProps('div', {\n ref: useMergedRefs(ref, optionRef),\n role: 'option',\n 'aria-disabled': disabled ? 'true' : undefined,\n 'aria-selected': `${selected}`,\n id,\n ...props,\n onClick,\n }),\n checkIcon: resolveShorthand(props.checkIcon, {\n required: true,\n defaultProps: {\n 'aria-hidden': 'true',\n children: CheckIcon,\n },\n }),\n active,\n disabled,\n focusVisible,\n multiselect,\n selected,\n };\n};\n"],"sourceRoot":"../src/"}
@@ -113,11 +113,12 @@ const useOptionStyles_unstable = state => {
113
113
  const {
114
114
  active,
115
115
  disabled,
116
+ focusVisible,
116
117
  multiselect,
117
118
  selected
118
119
  } = state;
119
120
  const styles = useStyles();
120
- state.root.className = react_1.mergeClasses(exports.optionClassNames.root, styles.root, active && styles.active, disabled && styles.disabled, selected && styles.selected, state.root.className);
121
+ state.root.className = react_1.mergeClasses(exports.optionClassNames.root, styles.root, active && focusVisible && styles.active, disabled && styles.disabled, selected && styles.selected, state.root.className);
121
122
 
122
123
  if (state.checkIcon) {
123
124
  state.checkIcon.className = react_1.mergeClasses(exports.optionClassNames.checkIcon, styles.checkIcon, state.checkIcon.className, multiselect && styles.multiselectCheck, selected && styles.selectedCheck, selected && multiselect && styles.selectedMultiselectCheck, disabled && styles.checkDisabled);
@@ -1 +1 @@
1
- {"version":3,"sources":["components/Option/useOptionStyles.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,aAAA,gBAAA,OAAA,CAAA,uBAAA,CAAA;;AAEA,MAAA,OAAA,gBAAA,OAAA,CAAA,gBAAA,CAAA;;AAGa,OAAA,CAAA,gBAAA,GAAgD;EAC3D,IAAI,EAAE,YADqD;EAE3D,SAAS,EAAE;AAFgD,CAAhD;AAKb;;AAEG;;AACH,MAAM,SAAS,gBAAG,OAAA,SAAA;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;EAAA;EAAA;IAAA;EAAA;EAAA;IAAA;IAAA;EAAA;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;EAAA;IAAA;EAAA;AAAA,EAAlB;AAkGA;;AAEG;;;AACI,MAAM,wBAAwB,GAAI,KAAD,IAAoC;EAC1E,MAAM;IAAE,MAAF;IAAU,QAAV;IAAoB,WAApB;IAAiC;EAAjC,IAA8C,KAApD;EACA,MAAM,MAAM,GAAG,SAAS,EAAxB;EACA,KAAK,CAAC,IAAN,CAAW,SAAX,GAAuB,OAAA,CAAA,YAAA,CACrB,OAAA,CAAA,gBAAA,CAAiB,IADI,EAErB,MAAM,CAAC,IAFc,EAGrB,MAAM,IAAI,MAAM,CAAC,MAHI,EAIrB,QAAQ,IAAI,MAAM,CAAC,QAJE,EAKrB,QAAQ,IAAI,MAAM,CAAC,QALE,EAMrB,KAAK,CAAC,IAAN,CAAW,SANU,CAAvB;;EASA,IAAI,KAAK,CAAC,SAAV,EAAqB;IACnB,KAAK,CAAC,SAAN,CAAgB,SAAhB,GAA4B,OAAA,CAAA,YAAA,CAC1B,OAAA,CAAA,gBAAA,CAAiB,SADS,EAE1B,MAAM,CAAC,SAFmB,EAG1B,KAAK,CAAC,SAAN,CAAgB,SAHU,EAI1B,WAAW,IAAI,MAAM,CAAC,gBAJI,EAK1B,QAAQ,IAAI,MAAM,CAAC,aALO,EAM1B,QAAQ,IAAI,WAAZ,IAA2B,MAAM,CAAC,wBANR,EAO1B,QAAQ,IAAI,MAAM,CAAC,aAPO,CAA5B;EASD;;EAED,OAAO,KAAP;AACD,CAzBM;;AAAM,OAAA,CAAA,wBAAA,GAAwB,wBAAxB","sourcesContent":["import { tokens } from '@fluentui/react-theme';\nimport { SlotClassNames } from '@fluentui/react-utilities';\nimport { makeStyles, mergeClasses, shorthands } from '@griffel/react';\nimport type { OptionSlots, OptionState } from './Option.types';\n\nexport const optionClassNames: SlotClassNames<OptionSlots> = {\n root: 'fui-Option',\n checkIcon: 'fui-Option__checkIcon',\n};\n\n/**\n * Styles for the root slot\n */\nconst useStyles = makeStyles({\n root: {\n alignItems: 'center',\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n color: tokens.colorNeutralForeground1,\n columnGap: tokens.spacingHorizontalXS,\n cursor: 'pointer',\n display: 'flex',\n fontFamily: tokens.fontFamilyBase,\n fontSize: tokens.fontSizeBase300,\n lineHeight: tokens.lineHeightBase300,\n ...shorthands.padding(tokens.spacingVerticalSNudge, tokens.spacingHorizontalS),\n position: 'relative',\n\n '&:hover': {\n backgroundColor: tokens.colorNeutralBackground1Hover,\n },\n\n '&:active': {\n backgroundColor: tokens.colorNeutralBackground1Pressed,\n },\n },\n\n active: {\n // taken from @fluentui/react-tabster\n // cannot use createFocusIndicatorStyle() directly, since we aren't using the :focus selector\n '::after': {\n content: '\"\"',\n position: 'absolute',\n pointerEvents: 'none',\n zIndex: 1,\n\n ...shorthands.borderStyle('solid'),\n ...shorthands.borderWidth('2px'),\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n ...shorthands.borderColor(tokens.colorStrokeFocus2),\n\n top: '-2px',\n bottom: '-2px',\n left: '-2px',\n right: '-2px',\n },\n },\n\n disabled: {\n color: tokens.colorNeutralForegroundDisabled,\n\n '&:hover': {\n backgroundColor: tokens.colorTransparentBackground,\n },\n\n '&:active': {\n backgroundColor: tokens.colorTransparentBackground,\n },\n\n '@media (forced-colors: active)': {\n color: 'GrayText',\n },\n },\n\n selected: {},\n\n checkIcon: {\n fontSize: tokens.fontSizeBase400,\n // Shift icon(s) to the left to give text content extra spacing without needing an extra node\n // This is done instead of gap since the extra space only exists between icon > content, not icon > icon\n marginLeft: `calc(${tokens.spacingHorizontalXXS} * -1)`,\n marginRight: tokens.spacingHorizontalXXS,\n visibility: 'hidden',\n\n '& svg': {\n display: 'block',\n },\n },\n\n multiselectCheck: {\n color: tokens.colorNeutralForeground3,\n fontSize: tokens.fontSizeBase500,\n visibility: 'visible',\n },\n\n selectedCheck: {\n visibility: 'visible',\n },\n\n selectedMultiselectCheck: {\n color: tokens.colorBrandBackground,\n },\n\n checkDisabled: {\n color: tokens.colorNeutralForegroundDisabled,\n\n '@media (forced-colors: active)': {\n color: 'GrayText',\n },\n },\n});\n\n/**\n * Apply styling to the Option slots based on the state\n */\nexport const useOptionStyles_unstable = (state: OptionState): OptionState => {\n const { active, disabled, multiselect, selected } = state;\n const styles = useStyles();\n state.root.className = mergeClasses(\n optionClassNames.root,\n styles.root,\n active && styles.active,\n disabled && styles.disabled,\n selected && styles.selected,\n state.root.className,\n );\n\n if (state.checkIcon) {\n state.checkIcon.className = mergeClasses(\n optionClassNames.checkIcon,\n styles.checkIcon,\n state.checkIcon.className,\n multiselect && styles.multiselectCheck,\n selected && styles.selectedCheck,\n selected && multiselect && styles.selectedMultiselectCheck,\n disabled && styles.checkDisabled,\n );\n }\n\n return state;\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["components/Option/useOptionStyles.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,aAAA,gBAAA,OAAA,CAAA,uBAAA,CAAA;;AAEA,MAAA,OAAA,gBAAA,OAAA,CAAA,gBAAA,CAAA;;AAGa,OAAA,CAAA,gBAAA,GAAgD;EAC3D,IAAI,EAAE,YADqD;EAE3D,SAAS,EAAE;AAFgD,CAAhD;AAKb;;AAEG;;AACH,MAAM,SAAS,gBAAG,OAAA,SAAA;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;EAAA;IAAA;IAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;IAAA;IAAA;EAAA;EAAA;IAAA;EAAA;EAAA;IAAA;EAAA;EAAA;IAAA;IAAA;EAAA;AAAA;EAAA;EAAA;EAAA;EAAA;IAAA;EAAA;IAAA;EAAA;AAAA,EAAlB;AAkGA;;AAEG;;;AACI,MAAM,wBAAwB,GAAI,KAAD,IAAoC;EAC1E,MAAM;IAAE,MAAF;IAAU,QAAV;IAAoB,YAApB;IAAkC,WAAlC;IAA+C;EAA/C,IAA4D,KAAlE;EACA,MAAM,MAAM,GAAG,SAAS,EAAxB;EACA,KAAK,CAAC,IAAN,CAAW,SAAX,GAAuB,OAAA,CAAA,YAAA,CACrB,OAAA,CAAA,gBAAA,CAAiB,IADI,EAErB,MAAM,CAAC,IAFc,EAGrB,MAAM,IAAI,YAAV,IAA0B,MAAM,CAAC,MAHZ,EAIrB,QAAQ,IAAI,MAAM,CAAC,QAJE,EAKrB,QAAQ,IAAI,MAAM,CAAC,QALE,EAMrB,KAAK,CAAC,IAAN,CAAW,SANU,CAAvB;;EASA,IAAI,KAAK,CAAC,SAAV,EAAqB;IACnB,KAAK,CAAC,SAAN,CAAgB,SAAhB,GAA4B,OAAA,CAAA,YAAA,CAC1B,OAAA,CAAA,gBAAA,CAAiB,SADS,EAE1B,MAAM,CAAC,SAFmB,EAG1B,KAAK,CAAC,SAAN,CAAgB,SAHU,EAI1B,WAAW,IAAI,MAAM,CAAC,gBAJI,EAK1B,QAAQ,IAAI,MAAM,CAAC,aALO,EAM1B,QAAQ,IAAI,WAAZ,IAA2B,MAAM,CAAC,wBANR,EAO1B,QAAQ,IAAI,MAAM,CAAC,aAPO,CAA5B;EASD;;EAED,OAAO,KAAP;AACD,CAzBM;;AAAM,OAAA,CAAA,wBAAA,GAAwB,wBAAxB","sourcesContent":["import { tokens } from '@fluentui/react-theme';\nimport { SlotClassNames } from '@fluentui/react-utilities';\nimport { makeStyles, mergeClasses, shorthands } from '@griffel/react';\nimport type { OptionSlots, OptionState } from './Option.types';\n\nexport const optionClassNames: SlotClassNames<OptionSlots> = {\n root: 'fui-Option',\n checkIcon: 'fui-Option__checkIcon',\n};\n\n/**\n * Styles for the root slot\n */\nconst useStyles = makeStyles({\n root: {\n alignItems: 'center',\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n color: tokens.colorNeutralForeground1,\n columnGap: tokens.spacingHorizontalXS,\n cursor: 'pointer',\n display: 'flex',\n fontFamily: tokens.fontFamilyBase,\n fontSize: tokens.fontSizeBase300,\n lineHeight: tokens.lineHeightBase300,\n ...shorthands.padding(tokens.spacingVerticalSNudge, tokens.spacingHorizontalS),\n position: 'relative',\n\n '&:hover': {\n backgroundColor: tokens.colorNeutralBackground1Hover,\n },\n\n '&:active': {\n backgroundColor: tokens.colorNeutralBackground1Pressed,\n },\n },\n\n active: {\n // taken from @fluentui/react-tabster\n // cannot use createFocusIndicatorStyle() directly, since we aren't using the :focus selector\n '::after': {\n content: '\"\"',\n position: 'absolute',\n pointerEvents: 'none',\n zIndex: 1,\n\n ...shorthands.borderStyle('solid'),\n ...shorthands.borderWidth('2px'),\n ...shorthands.borderRadius(tokens.borderRadiusMedium),\n ...shorthands.borderColor(tokens.colorStrokeFocus2),\n\n top: '-2px',\n bottom: '-2px',\n left: '-2px',\n right: '-2px',\n },\n },\n\n disabled: {\n color: tokens.colorNeutralForegroundDisabled,\n\n '&:hover': {\n backgroundColor: tokens.colorTransparentBackground,\n },\n\n '&:active': {\n backgroundColor: tokens.colorTransparentBackground,\n },\n\n '@media (forced-colors: active)': {\n color: 'GrayText',\n },\n },\n\n selected: {},\n\n checkIcon: {\n fontSize: tokens.fontSizeBase400,\n // Shift icon(s) to the left to give text content extra spacing without needing an extra node\n // This is done instead of gap since the extra space only exists between icon > content, not icon > icon\n marginLeft: `calc(${tokens.spacingHorizontalXXS} * -1)`,\n marginRight: tokens.spacingHorizontalXXS,\n visibility: 'hidden',\n\n '& svg': {\n display: 'block',\n },\n },\n\n multiselectCheck: {\n color: tokens.colorNeutralForeground3,\n fontSize: tokens.fontSizeBase500,\n visibility: 'visible',\n },\n\n selectedCheck: {\n visibility: 'visible',\n },\n\n selectedMultiselectCheck: {\n color: tokens.colorBrandBackground,\n },\n\n checkDisabled: {\n color: tokens.colorNeutralForegroundDisabled,\n\n '@media (forced-colors: active)': {\n color: 'GrayText',\n },\n },\n});\n\n/**\n * Apply styling to the Option slots based on the state\n */\nexport const useOptionStyles_unstable = (state: OptionState): OptionState => {\n const { active, disabled, focusVisible, multiselect, selected } = state;\n const styles = useStyles();\n state.root.className = mergeClasses(\n optionClassNames.root,\n styles.root,\n active && focusVisible && styles.active,\n disabled && styles.disabled,\n selected && styles.selected,\n state.root.className,\n );\n\n if (state.checkIcon) {\n state.checkIcon.className = mergeClasses(\n optionClassNames.checkIcon,\n styles.checkIcon,\n state.checkIcon.className,\n multiselect && styles.multiselectCheck,\n selected && styles.selectedCheck,\n selected && multiselect && styles.selectedMultiselectCheck,\n disabled && styles.checkDisabled,\n );\n }\n\n return state;\n};\n"],"sourceRoot":"../src/"}
@@ -11,15 +11,22 @@ const react_context_selector_1 = /*#__PURE__*/require("@fluentui/react-context-s
11
11
  exports.ComboboxContext = /*#__PURE__*/react_context_selector_1.createContext({
12
12
  activeOption: undefined,
13
13
  appearance: 'outline',
14
+ focusVisible: false,
15
+ open: false,
14
16
 
15
- onOptionClick() {// noop
17
+ registerOption() {
18
+ return () => undefined;
16
19
  },
17
20
 
18
- open: false,
19
21
  selectedOptions: [],
20
22
 
21
- registerOption() {
22
- return () => undefined;
23
+ selectOption() {// noop
24
+ },
25
+
26
+ setActiveOption() {// noop
27
+ },
28
+
29
+ setOpen() {// noop
23
30
  },
24
31
 
25
32
  size: 'medium'
@@ -1 +1 @@
1
- {"version":3,"sources":["contexts/ComboboxContext.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,wBAAA,gBAAA,OAAA,CAAA,kCAAA,CAAA,C,CAWA;;;AACa,OAAA,CAAA,eAAA,gBAAkB,wBAAA,CAAA,aAAA,CAAoC;EACjE,YAAY,EAAE,SADmD;EAEjE,UAAU,EAAE,SAFqD;;EAGjE,aAAa,GAAA,CACX;EACD,CALgE;;EAMjE,IAAI,EAAE,KAN2D;EAOjE,eAAe,EAAE,EAPgD;;EAQjE,cAAc,GAAA;IACZ,OAAO,MAAM,SAAb;EACD,CAVgE;;EAWjE,IAAI,EAAE;AAX2D,CAApC,CAAlB","sourcesContent":["import { createContext } from '@fluentui/react-context-selector';\nimport { ComboboxState } from '../components/Combobox/Combobox.types';\n\n/**\n * Context shared with Combobox, Listbox, & Options\n */\nexport type ComboboxContextValue = Pick<\n ComboboxState,\n 'activeOption' | 'appearance' | 'onOptionClick' | 'open' | 'registerOption' | 'selectedOptions' | 'size'\n>;\n\n// eslint-disable-next-line @fluentui/no-context-default-value\nexport const ComboboxContext = createContext<ComboboxContextValue>({\n activeOption: undefined,\n appearance: 'outline',\n onOptionClick() {\n // noop\n },\n open: false,\n selectedOptions: [],\n registerOption() {\n return () => undefined;\n },\n size: 'medium',\n});\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["contexts/ComboboxContext.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,wBAAA,gBAAA,OAAA,CAAA,kCAAA,CAAA,C,CAoBA;;;AACa,OAAA,CAAA,eAAA,gBAAkB,wBAAA,CAAA,aAAA,CAAoC;EACjE,YAAY,EAAE,SADmD;EAEjE,UAAU,EAAE,SAFqD;EAGjE,YAAY,EAAE,KAHmD;EAIjE,IAAI,EAAE,KAJ2D;;EAKjE,cAAc,GAAA;IACZ,OAAO,MAAM,SAAb;EACD,CAPgE;;EAQjE,eAAe,EAAE,EARgD;;EASjE,YAAY,GAAA,CACV;EACD,CAXgE;;EAYjE,eAAe,GAAA,CACb;EACD,CAdgE;;EAejE,OAAO,GAAA,CACL;EACD,CAjBgE;;EAkBjE,IAAI,EAAE;AAlB2D,CAApC,CAAlB","sourcesContent":["import { createContext } from '@fluentui/react-context-selector';\nimport { ComboboxState } from '../components/Combobox/Combobox.types';\n\n/**\n * Context shared with Combobox, Listbox, & Options\n */\nexport type ComboboxContextValue = Pick<\n ComboboxState,\n | 'activeOption'\n | 'appearance'\n | 'focusVisible'\n | 'open'\n | 'registerOption'\n | 'selectedOptions'\n | 'selectOption'\n | 'setActiveOption'\n | 'setOpen'\n | 'size'\n>;\n\n// eslint-disable-next-line @fluentui/no-context-default-value\nexport const ComboboxContext = createContext<ComboboxContextValue>({\n activeOption: undefined,\n appearance: 'outline',\n focusVisible: false,\n open: false,\n registerOption() {\n return () => undefined;\n },\n selectedOptions: [],\n selectOption() {\n // noop\n },\n setActiveOption() {\n // noop\n },\n setOpen() {\n // noop\n },\n size: 'medium',\n});\n"],"sourceRoot":"../src/"}
@@ -10,15 +10,20 @@ const react_context_selector_1 = /*#__PURE__*/require("@fluentui/react-context-s
10
10
 
11
11
  exports.ListboxContext = /*#__PURE__*/react_context_selector_1.createContext({
12
12
  activeOption: undefined,
13
+ focusVisible: false,
13
14
  multiselect: false,
14
15
 
15
- onOptionClick() {// noop
16
- },
17
-
18
16
  registerOption() {
19
17
  return () => undefined;
20
18
  },
21
19
 
22
- selectedOptions: []
20
+ selectedOptions: [],
21
+
22
+ selectOption() {// noop
23
+ },
24
+
25
+ setActiveOption() {// noop
26
+ }
27
+
23
28
  });
24
29
  //# sourceMappingURL=ListboxContext.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["contexts/ListboxContext.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,wBAAA,gBAAA,OAAA,CAAA,kCAAA,CAAA,C,CAWA;;;AACa,OAAA,CAAA,cAAA,gBAAiB,wBAAA,CAAA,aAAA,CAAmC;EAC/D,YAAY,EAAE,SADiD;EAE/D,WAAW,EAAE,KAFkD;;EAG/D,aAAa,GAAA,CACX;EACD,CAL8D;;EAM/D,cAAc,GAAA;IACZ,OAAO,MAAM,SAAb;EACD,CAR8D;;EAS/D,eAAe,EAAE;AAT8C,CAAnC,CAAjB","sourcesContent":["import { createContext } from '@fluentui/react-context-selector';\nimport { ListboxState } from '../components/Listbox/Listbox.types';\n\n/**\n * Context shared with all Listbox Options\n */\nexport type ListboxContextValue = Pick<\n ListboxState,\n 'activeOption' | 'multiselect' | 'onOptionClick' | 'registerOption' | 'selectedOptions'\n>;\n\n// eslint-disable-next-line @fluentui/no-context-default-value\nexport const ListboxContext = createContext<ListboxContextValue>({\n activeOption: undefined,\n multiselect: false,\n onOptionClick() {\n // noop\n },\n registerOption() {\n return () => undefined;\n },\n selectedOptions: [],\n});\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["contexts/ListboxContext.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,wBAAA,gBAAA,OAAA,CAAA,kCAAA,CAAA,C,CAiBA;;;AACa,OAAA,CAAA,cAAA,gBAAiB,wBAAA,CAAA,aAAA,CAAmC;EAC/D,YAAY,EAAE,SADiD;EAE/D,YAAY,EAAE,KAFiD;EAG/D,WAAW,EAAE,KAHkD;;EAI/D,cAAc,GAAA;IACZ,OAAO,MAAM,SAAb;EACD,CAN8D;;EAO/D,eAAe,EAAE,EAP8C;;EAQ/D,YAAY,GAAA,CACV;EACD,CAV8D;;EAW/D,eAAe,GAAA,CACb;EACD;;AAb8D,CAAnC,CAAjB","sourcesContent":["import { createContext } from '@fluentui/react-context-selector';\nimport { ListboxState } from '../components/Listbox/Listbox.types';\n\n/**\n * Context shared with all Listbox Options\n */\nexport type ListboxContextValue = Pick<\n ListboxState,\n | 'activeOption'\n | 'focusVisible'\n | 'multiselect'\n | 'registerOption'\n | 'selectedOptions'\n | 'selectOption'\n | 'setActiveOption'\n>;\n\n// eslint-disable-next-line @fluentui/no-context-default-value\nexport const ListboxContext = createContext<ListboxContextValue>({\n activeOption: undefined,\n focusVisible: false,\n multiselect: false,\n registerOption() {\n return () => undefined;\n },\n selectedOptions: [],\n selectOption() {\n // noop\n },\n setActiveOption() {\n // noop\n },\n});\n"],"sourceRoot":"../src/"}
@@ -9,19 +9,25 @@ function useComboboxContextValues(state) {
9
9
  const {
10
10
  activeOption,
11
11
  appearance,
12
- onOptionClick,
12
+ focusVisible,
13
13
  open,
14
14
  registerOption,
15
15
  selectedOptions,
16
+ selectOption,
17
+ setActiveOption,
18
+ setOpen,
16
19
  size
17
20
  } = state;
18
21
  const combobox = {
19
22
  activeOption,
20
23
  appearance,
24
+ focusVisible,
21
25
  open,
22
- onOptionClick,
23
26
  registerOption,
24
27
  selectedOptions,
28
+ selectOption,
29
+ setActiveOption,
30
+ setOpen,
25
31
  size
26
32
  };
27
33
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["contexts/useComboboxContextValues.ts"],"names":[],"mappings":";;;;;;;AAEA,SAAgB,wBAAhB,CAAyC,KAAzC,EAAiE;EAC/D,MAAM;IAAE,YAAF;IAAgB,UAAhB;IAA4B,aAA5B;IAA2C,IAA3C;IAAiD,cAAjD;IAAiE,eAAjE;IAAkF;EAAlF,IAA2F,KAAjG;EAEA,MAAM,QAAQ,GAAG;IACf,YADe;IAEf,UAFe;IAGf,IAHe;IAIf,aAJe;IAKf,cALe;IAMf,eANe;IAOf;EAPe,CAAjB;EAUA,OAAO;IAAE;EAAF,CAAP;AACD;;AAdD,OAAA,CAAA,wBAAA,GAAA,wBAAA","sourcesContent":["import { ComboboxBaseContextValues, ComboboxBaseState } from '../utils/ComboboxBase.types';\n\nexport function useComboboxContextValues(state: ComboboxBaseState): ComboboxBaseContextValues {\n const { activeOption, appearance, onOptionClick, open, registerOption, selectedOptions, size } = state;\n\n const combobox = {\n activeOption,\n appearance,\n open,\n onOptionClick,\n registerOption,\n selectedOptions,\n size,\n };\n\n return { combobox };\n}\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["contexts/useComboboxContextValues.ts"],"names":[],"mappings":";;;;;;;AAEA,SAAgB,wBAAhB,CAAyC,KAAzC,EAAiE;EAC/D,MAAM;IACJ,YADI;IAEJ,UAFI;IAGJ,YAHI;IAIJ,IAJI;IAKJ,cALI;IAMJ,eANI;IAOJ,YAPI;IAQJ,eARI;IASJ,OATI;IAUJ;EAVI,IAWF,KAXJ;EAaA,MAAM,QAAQ,GAAG;IACf,YADe;IAEf,UAFe;IAGf,YAHe;IAIf,IAJe;IAKf,cALe;IAMf,eANe;IAOf,YAPe;IAQf,eARe;IASf,OATe;IAUf;EAVe,CAAjB;EAaA,OAAO;IAAE;EAAF,CAAP;AACD;;AA5BD,OAAA,CAAA,wBAAA,GAAA,wBAAA","sourcesContent":["import { ComboboxBaseContextValues, ComboboxBaseState } from '../utils/ComboboxBase.types';\n\nexport function useComboboxContextValues(state: ComboboxBaseState): ComboboxBaseContextValues {\n const {\n activeOption,\n appearance,\n focusVisible,\n open,\n registerOption,\n selectedOptions,\n selectOption,\n setActiveOption,\n setOpen,\n size,\n } = state;\n\n const combobox = {\n activeOption,\n appearance,\n focusVisible,\n open,\n registerOption,\n selectedOptions,\n selectOption,\n setActiveOption,\n setOpen,\n size,\n };\n\n return { combobox };\n}\n"],"sourceRoot":"../src/"}
@@ -13,20 +13,24 @@ function useListboxContextValues(state) {
13
13
  const hasComboboxContext = react_context_selector_1.useHasParentContext(ComboboxContext_1.ComboboxContext);
14
14
  const {
15
15
  activeOption,
16
+ focusVisible,
16
17
  multiselect,
17
- onOptionClick,
18
18
  registerOption,
19
- selectedOptions
19
+ selectedOptions,
20
+ selectOption,
21
+ setActiveOption
20
22
  } = state; // get register/unregister functions from parent combobox context
21
23
 
22
24
  const comboboxRegisterOption = react_context_selector_1.useContextSelector(ComboboxContext_1.ComboboxContext, ctx => ctx.registerOption);
23
25
  const registerOptionValue = hasComboboxContext ? comboboxRegisterOption : registerOption;
24
26
  const listbox = {
25
27
  activeOption,
28
+ focusVisible,
26
29
  multiselect,
27
- onOptionClick,
30
+ registerOption: registerOptionValue,
28
31
  selectedOptions,
29
- registerOption: registerOptionValue
32
+ selectOption,
33
+ setActiveOption
30
34
  };
31
35
  return {
32
36
  listbox
@@ -1 +1 @@
1
- {"version":3,"sources":["contexts/useListboxContextValues.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,wBAAA,gBAAA,OAAA,CAAA,kCAAA,CAAA;;AAEA,MAAA,iBAAA,gBAAA,OAAA,CAAA,mBAAA,CAAA;;AAEA,SAAgB,uBAAhB,CAAwC,KAAxC,EAA2D;EACzD,MAAM,kBAAkB,GAAG,wBAAA,CAAA,mBAAA,CAAoB,iBAAA,CAAA,eAApB,CAA3B;EACA,MAAM;IAAE,YAAF;IAAgB,WAAhB;IAA6B,aAA7B;IAA4C,cAA5C;IAA4D;EAA5D,IAAgF,KAAtF,CAFyD,CAIzD;;EACA,MAAM,sBAAsB,GAAG,wBAAA,CAAA,kBAAA,CAAmB,iBAAA,CAAA,eAAnB,EAAoC,GAAG,IAAI,GAAG,CAAC,cAA/C,CAA/B;EAEA,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,sBAAH,GAA4B,cAA1E;EAEA,MAAM,OAAO,GAAG;IACd,YADc;IAEd,WAFc;IAGd,aAHc;IAId,eAJc;IAKd,cAAc,EAAE;EALF,CAAhB;EAQA,OAAO;IAAE;EAAF,CAAP;AACD;;AAlBD,OAAA,CAAA,uBAAA,GAAA,uBAAA","sourcesContent":["import { useContextSelector, useHasParentContext } from '@fluentui/react-context-selector';\nimport { ListboxContextValues, ListboxState } from '../components/Listbox/Listbox.types';\nimport { ComboboxContext } from './ComboboxContext';\n\nexport function useListboxContextValues(state: ListboxState): ListboxContextValues {\n const hasComboboxContext = useHasParentContext(ComboboxContext);\n const { activeOption, multiselect, onOptionClick, registerOption, selectedOptions } = state;\n\n // get register/unregister functions from parent combobox context\n const comboboxRegisterOption = useContextSelector(ComboboxContext, ctx => ctx.registerOption);\n\n const registerOptionValue = hasComboboxContext ? comboboxRegisterOption : registerOption;\n\n const listbox = {\n activeOption,\n multiselect,\n onOptionClick,\n selectedOptions,\n registerOption: registerOptionValue,\n };\n\n return { listbox };\n}\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["contexts/useListboxContextValues.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,wBAAA,gBAAA,OAAA,CAAA,kCAAA,CAAA;;AAEA,MAAA,iBAAA,gBAAA,OAAA,CAAA,mBAAA,CAAA;;AAEA,SAAgB,uBAAhB,CAAwC,KAAxC,EAA2D;EACzD,MAAM,kBAAkB,GAAG,wBAAA,CAAA,mBAAA,CAAoB,iBAAA,CAAA,eAApB,CAA3B;EACA,MAAM;IACJ,YADI;IAEJ,YAFI;IAGJ,WAHI;IAIJ,cAJI;IAKJ,eALI;IAMJ,YANI;IAOJ;EAPI,IAQF,KARJ,CAFyD,CAYzD;;EACA,MAAM,sBAAsB,GAAG,wBAAA,CAAA,kBAAA,CAAmB,iBAAA,CAAA,eAAnB,EAAoC,GAAG,IAAI,GAAG,CAAC,cAA/C,CAA/B;EAEA,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,sBAAH,GAA4B,cAA1E;EAEA,MAAM,OAAO,GAAG;IACd,YADc;IAEd,YAFc;IAGd,WAHc;IAId,cAAc,EAAE,mBAJF;IAKd,eALc;IAMd,YANc;IAOd;EAPc,CAAhB;EAUA,OAAO;IAAE;EAAF,CAAP;AACD;;AA5BD,OAAA,CAAA,uBAAA,GAAA,uBAAA","sourcesContent":["import { useContextSelector, useHasParentContext } from '@fluentui/react-context-selector';\nimport { ListboxContextValues, ListboxState } from '../components/Listbox/Listbox.types';\nimport { ComboboxContext } from './ComboboxContext';\n\nexport function useListboxContextValues(state: ListboxState): ListboxContextValues {\n const hasComboboxContext = useHasParentContext(ComboboxContext);\n const {\n activeOption,\n focusVisible,\n multiselect,\n registerOption,\n selectedOptions,\n selectOption,\n setActiveOption,\n } = state;\n\n // get register/unregister functions from parent combobox context\n const comboboxRegisterOption = useContextSelector(ComboboxContext, ctx => ctx.registerOption);\n\n const registerOptionValue = hasComboboxContext ? comboboxRegisterOption : registerOption;\n\n const listbox = {\n activeOption,\n focusVisible,\n multiselect,\n registerOption: registerOptionValue,\n selectedOptions,\n selectOption,\n setActiveOption,\n };\n\n return { listbox };\n}\n"],"sourceRoot":"../src/"}
@@ -52,11 +52,11 @@ function getDropdownActionFromKey(e, options = {}) {
52
52
  } // navigation interactions
53
53
 
54
54
 
55
- if (code === keys.ArrowRight || code === keys.ArrowDown) {
55
+ if (code === keys.ArrowDown) {
56
56
  return 'Next';
57
57
  }
58
58
 
59
- if (code === keys.ArrowLeft || code === keys.ArrowUp) {
59
+ if (code === keys.ArrowUp) {
60
60
  return 'Previous';
61
61
  }
62
62
 
@@ -109,13 +109,6 @@ function getIndexFromAction(action, currentIndex, maxIndex) {
109
109
 
110
110
  case 'PageUp':
111
111
  return Math.max(0, currentIndex - 10);
112
- // case 'Type':
113
- // // always prevent default and stop propagation when typing
114
- // e.preventDefault();
115
- // e.stopPropagation();
116
- // const matchingIndex = findByCharacter(e.key);
117
- // return matchingIndex > -1 ? matchingIndex : activeIndex;
118
- // break;
119
112
 
120
113
  default:
121
114
  return currentIndex;
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/dropdownKeyActions.ts"],"names":[],"mappings":"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","sourcesContent":["import * as keys from '@fluentui/keyboard-keys';\nimport * as React from 'react';\n\n/**\n * enum of actions available in any type of managed dropdown control\n * e.g. combobox, select, datepicker, menu\n */\nexport type DropdownActions =\n | 'Close'\n | 'CloseSelect'\n | 'First'\n | 'Last'\n | 'Next'\n | 'None'\n | 'Open'\n | 'PageDown'\n | 'PageUp'\n | 'Previous'\n | 'Select'\n | 'Tab'\n | 'Type';\n\nexport interface DropdownActionOptions {\n open?: boolean;\n multiselect?: boolean;\n}\n\n/**\n * Converts a keyboard interaction into a defined action\n */\nexport function getDropdownActionFromKey(\n e: KeyboardEvent | React.KeyboardEvent,\n options: DropdownActionOptions = {},\n): DropdownActions {\n const { open = true, multiselect = false } = options;\n const code = e.key;\n const { altKey, ctrlKey, key, metaKey } = e;\n\n // typing action occurs whether open or closed\n if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {\n return 'Type';\n }\n\n // handle opening the dropdown if closed\n if (!open) {\n if (code === keys.ArrowDown || code === keys.ArrowUp || code === keys.Enter || code === keys.Space) {\n return 'Open';\n }\n\n // if the dropdown is closed and an action did not match the above, do nothing\n return 'None';\n }\n\n // select or close actions\n if ((code === keys.ArrowUp && altKey) || code === keys.Enter || (!multiselect && code === keys.Space)) {\n return 'CloseSelect';\n }\n if (multiselect && code === keys.Space) {\n return 'Select';\n }\n if (code === keys.Escape) {\n return 'Close';\n }\n\n // navigation interactions\n if (code === keys.ArrowRight || code === keys.ArrowDown) {\n return 'Next';\n }\n if (code === keys.ArrowLeft || code === keys.ArrowUp) {\n return 'Previous';\n }\n if (code === keys.Home) {\n return 'First';\n }\n if (code === keys.End) {\n return 'Last';\n }\n if (code === keys.PageUp) {\n return 'PageUp';\n }\n if (code === keys.PageDown) {\n return 'PageDown';\n }\n if (code === keys.Tab) {\n return 'Tab';\n }\n\n // if nothing matched, return none\n return 'None';\n}\n\n/**\n * Returns the requested option index from an action\n */\nexport function getIndexFromAction(action: DropdownActions, currentIndex: number, maxIndex: number): number {\n switch (action) {\n case 'Next':\n return Math.min(maxIndex, currentIndex + 1);\n break;\n case 'Previous':\n return Math.max(0, currentIndex - 1);\n case 'First':\n return 0;\n case 'Last':\n return maxIndex;\n case 'PageDown':\n return Math.min(maxIndex, currentIndex + 10);\n case 'PageUp':\n return Math.max(0, currentIndex - 10);\n // case 'Type':\n // // always prevent default and stop propagation when typing\n // e.preventDefault();\n // e.stopPropagation();\n\n // const matchingIndex = findByCharacter(e.key);\n // return matchingIndex > -1 ? matchingIndex : activeIndex;\n // break;\n default:\n return currentIndex;\n }\n}\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/dropdownKeyActions.ts"],"names":[],"mappings":"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","sourcesContent":["import * as keys from '@fluentui/keyboard-keys';\nimport * as React from 'react';\n\n/**\n * enum of actions available in any type of managed dropdown control\n * e.g. combobox, select, datepicker, menu\n */\nexport type DropdownActions =\n | 'Close'\n | 'CloseSelect'\n | 'First'\n | 'Last'\n | 'Next'\n | 'None'\n | 'Open'\n | 'PageDown'\n | 'PageUp'\n | 'Previous'\n | 'Select'\n | 'Tab'\n | 'Type';\n\nexport interface DropdownActionOptions {\n open?: boolean;\n multiselect?: boolean;\n}\n\n/**\n * Converts a keyboard interaction into a defined action\n */\nexport function getDropdownActionFromKey(\n e: KeyboardEvent | React.KeyboardEvent,\n options: DropdownActionOptions = {},\n): DropdownActions {\n const { open = true, multiselect = false } = options;\n const code = e.key;\n const { altKey, ctrlKey, key, metaKey } = e;\n\n // typing action occurs whether open or closed\n if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {\n return 'Type';\n }\n\n // handle opening the dropdown if closed\n if (!open) {\n if (code === keys.ArrowDown || code === keys.ArrowUp || code === keys.Enter || code === keys.Space) {\n return 'Open';\n }\n\n // if the dropdown is closed and an action did not match the above, do nothing\n return 'None';\n }\n\n // select or close actions\n if ((code === keys.ArrowUp && altKey) || code === keys.Enter || (!multiselect && code === keys.Space)) {\n return 'CloseSelect';\n }\n if (multiselect && code === keys.Space) {\n return 'Select';\n }\n if (code === keys.Escape) {\n return 'Close';\n }\n\n // navigation interactions\n if (code === keys.ArrowDown) {\n return 'Next';\n }\n if (code === keys.ArrowUp) {\n return 'Previous';\n }\n if (code === keys.Home) {\n return 'First';\n }\n if (code === keys.End) {\n return 'Last';\n }\n if (code === keys.PageUp) {\n return 'PageUp';\n }\n if (code === keys.PageDown) {\n return 'PageDown';\n }\n if (code === keys.Tab) {\n return 'Tab';\n }\n\n // if nothing matched, return none\n return 'None';\n}\n\n/**\n * Returns the requested option index from an action\n */\nexport function getIndexFromAction(action: DropdownActions, currentIndex: number, maxIndex: number): number {\n switch (action) {\n case 'Next':\n return Math.min(maxIndex, currentIndex + 1);\n break;\n case 'Previous':\n return Math.max(0, currentIndex - 1);\n case 'First':\n return 0;\n case 'Last':\n return maxIndex;\n case 'PageDown':\n return Math.min(maxIndex, currentIndex + 10);\n case 'PageUp':\n return Math.max(0, currentIndex - 10);\n default:\n return currentIndex;\n }\n}\n"],"sourceRoot":"../src/"}
@@ -28,21 +28,31 @@ const useComboboxBaseState = props => {
28
28
  const optionCollection = useOptionCollection_1.useOptionCollection();
29
29
  const {
30
30
  getOptionAtIndex,
31
- getOptionById,
32
31
  getOptionsMatchingValue
33
32
  } = optionCollection;
34
- const [activeOption, setActiveOption] = React.useState();
33
+ const [activeOption, setActiveOption] = React.useState(); // track whether keyboard focus outline should be shown
34
+ // tabster/keyborg doesn't work here, since the actual keyboard focus target doesn't move
35
+
36
+ const [focusVisible, setFocusVisible] = React.useState(false); // track focused state to conditionally render collapsed listbox
37
+
38
+ const [hasFocus, setHasFocus] = React.useState(false);
39
+ const ignoreNextBlur = React.useRef(false);
40
+ const selectionState = useSelection_1.useSelection(props);
35
41
  const {
36
- selectedOptions,
37
- selectOption
38
- } = useSelection_1.useSelection(props); // update value based on selectedOptions
42
+ selectedOptions
43
+ } = selectionState; // calculate value based on props, internal value changes, and selected options
39
44
 
40
45
  const isFirstMount = react_utilities_1.useFirstMount();
46
+ const [controllableValue, setValue] = react_utilities_1.useControllableState({
47
+ state: props.value,
48
+ initialState: undefined
49
+ });
41
50
  const value = React.useMemo(() => {
42
- // don't compute value if it is defined through props,
43
- if (props.value !== undefined) {
44
- return props.value;
45
- }
51
+ // don't compute the value if it is defined through props or setValue,
52
+ if (controllableValue !== undefined) {
53
+ return controllableValue;
54
+ } // handle defaultValue here, so it is overridden by selection
55
+
46
56
 
47
57
  if (isFirstMount && props.defaultValue !== undefined) {
48
58
  return props.defaultValue;
@@ -53,7 +63,7 @@ const useComboboxBaseState = props => {
53
63
  }
54
64
 
55
65
  return selectedOptions[0];
56
- }, [isFirstMount, multiselect, props.defaultValue, props.value, selectedOptions]); // Handle open state, which is shared with options in context
66
+ }, [controllableValue, isFirstMount, multiselect, props.defaultValue, selectedOptions]); // Handle open state, which is shared with options in context
57
67
 
58
68
  const [open, setOpenState] = react_utilities_1.useControllableState({
59
69
  state: props.open,
@@ -66,20 +76,11 @@ const useComboboxBaseState = props => {
66
76
  open: newState
67
77
  });
68
78
  setOpenState(newState);
69
- };
70
-
71
- const onOptionClick = (event, option) => {
72
- // clicked option should always become active option
73
- setActiveOption(getOptionById(option.id)); // close on option click for single-select
74
-
75
- !multiselect && setOpen(event, false); // handle selection change
76
-
77
- selectOption(event, option);
78
79
  }; // update active option based on change in open state
79
80
 
80
81
 
81
82
  React.useEffect(() => {
82
- if (open) {
83
+ if (open && !activeOption) {
83
84
  // if there is a selection, start at the most recently selected item
84
85
  if (selectedOptions.length > 0) {
85
86
  const lastSelectedOption = getOptionsMatchingValue(v => v === selectedOptions[selectedOptions.length - 1]).pop();
@@ -88,7 +89,7 @@ const useComboboxBaseState = props => {
88
89
  else {
89
90
  setActiveOption(getOptionAtIndex(0));
90
91
  }
91
- } else {
92
+ } else if (!open) {
92
93
  // reset the active option when closing
93
94
  setActiveOption(undefined);
94
95
  } // this should only be run in response to changes in the open state
@@ -96,15 +97,19 @@ const useComboboxBaseState = props => {
96
97
 
97
98
  }, [open]);
98
99
  return { ...optionCollection,
100
+ ...selectionState,
99
101
  activeOption,
100
102
  appearance,
103
+ focusVisible,
104
+ hasFocus,
105
+ ignoreNextBlur,
101
106
  inlinePopup,
102
- onOptionClick,
103
107
  open,
104
- selectedOptions,
105
- selectOption,
106
108
  setActiveOption,
109
+ setFocusVisible,
110
+ setHasFocus,
107
111
  setOpen,
112
+ setValue,
108
113
  size,
109
114
  value
110
115
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/useComboboxBaseState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { useControllableState, useFirstMount } from '@fluentui/react-utilities';\nimport { useOptionCollection } from '../utils/useOptionCollection';\nimport { OptionValue } from '../utils/OptionCollection.types';\nimport { useSelection } from '../utils/useSelection';\nimport type { ComboboxBaseProps, ComboboxBaseOpenEvents } from './ComboboxBase.types';\n\n/**\n * State shared between Combobox and Dropdown components\n */\nexport const useComboboxBaseState = (props: ComboboxBaseProps) => {\n const { appearance = 'outline', inlinePopup = false, multiselect, onOpenChange, size = 'medium' } = props;\n\n const optionCollection = useOptionCollection();\n const { getOptionAtIndex, getOptionById, getOptionsMatchingValue } = optionCollection;\n\n const [activeOption, setActiveOption] = React.useState<OptionValue | undefined>();\n const { selectedOptions, selectOption } = useSelection(props);\n\n // update value based on selectedOptions\n const isFirstMount = useFirstMount();\n const value = React.useMemo(() => {\n // don't compute value if it is defined through props,\n if (props.value !== undefined) {\n return props.value;\n }\n\n if (isFirstMount && props.defaultValue !== undefined) {\n return props.defaultValue;\n }\n\n if (multiselect) {\n return selectedOptions.join(', ');\n }\n\n return selectedOptions[0];\n }, [isFirstMount, multiselect, props.defaultValue, props.value, selectedOptions]);\n\n // Handle open state, which is shared with options in context\n const [open, setOpenState] = useControllableState({\n state: props.open,\n defaultState: props.defaultOpen,\n initialState: false,\n });\n\n const setOpen = (event: ComboboxBaseOpenEvents, newState: boolean) => {\n onOpenChange?.(event, { open: newState });\n setOpenState(newState);\n };\n\n const onOptionClick = (event: React.MouseEvent<HTMLElement>, option: OptionValue) => {\n // clicked option should always become active option\n setActiveOption(getOptionById(option.id));\n\n // close on option click for single-select\n !multiselect && setOpen(event, false);\n\n // handle selection change\n selectOption(event, option);\n };\n\n // update active option based on change in open state\n React.useEffect(() => {\n if (open) {\n // if there is a selection, start at the most recently selected item\n if (selectedOptions.length > 0) {\n const lastSelectedOption = getOptionsMatchingValue(\n v => v === selectedOptions[selectedOptions.length - 1],\n ).pop();\n lastSelectedOption && setActiveOption(lastSelectedOption);\n }\n // default to starting at the first option\n else {\n setActiveOption(getOptionAtIndex(0));\n }\n } else {\n // reset the active option when closing\n setActiveOption(undefined);\n }\n // this should only be run in response to changes in the open state\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n return {\n ...optionCollection,\n activeOption,\n appearance,\n inlinePopup,\n onOptionClick,\n open,\n selectedOptions,\n selectOption,\n setActiveOption,\n setOpen,\n size,\n value,\n };\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/useComboboxBaseState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { useControllableState, useFirstMount } from '@fluentui/react-utilities';\nimport { useOptionCollection } from '../utils/useOptionCollection';\nimport { OptionValue } from '../utils/OptionCollection.types';\nimport { useSelection } from '../utils/useSelection';\nimport type { ComboboxBaseProps, ComboboxBaseOpenEvents } from './ComboboxBase.types';\n\n/**\n * State shared between Combobox and Dropdown components\n */\nexport const useComboboxBaseState = (props: ComboboxBaseProps) => {\n const { appearance = 'outline', inlinePopup = false, multiselect, onOpenChange, size = 'medium' } = props;\n\n const optionCollection = useOptionCollection();\n const { getOptionAtIndex, getOptionsMatchingValue } = optionCollection;\n\n const [activeOption, setActiveOption] = React.useState<OptionValue | undefined>();\n\n // track whether keyboard focus outline should be shown\n // tabster/keyborg doesn't work here, since the actual keyboard focus target doesn't move\n const [focusVisible, setFocusVisible] = React.useState(false);\n\n // track focused state to conditionally render collapsed listbox\n const [hasFocus, setHasFocus] = React.useState(false);\n\n const ignoreNextBlur = React.useRef(false);\n\n const selectionState = useSelection(props);\n const { selectedOptions } = selectionState;\n\n // calculate value based on props, internal value changes, and selected options\n const isFirstMount = useFirstMount();\n const [controllableValue, setValue] = useControllableState({\n state: props.value,\n initialState: undefined,\n });\n\n const value = React.useMemo(() => {\n // don't compute the value if it is defined through props or setValue,\n if (controllableValue !== undefined) {\n return controllableValue;\n }\n\n // handle defaultValue here, so it is overridden by selection\n if (isFirstMount && props.defaultValue !== undefined) {\n return props.defaultValue;\n }\n\n if (multiselect) {\n return selectedOptions.join(', ');\n }\n\n return selectedOptions[0];\n }, [controllableValue, isFirstMount, multiselect, props.defaultValue, selectedOptions]);\n\n // Handle open state, which is shared with options in context\n const [open, setOpenState] = useControllableState({\n state: props.open,\n defaultState: props.defaultOpen,\n initialState: false,\n });\n\n const setOpen = (event: ComboboxBaseOpenEvents, newState: boolean) => {\n onOpenChange?.(event, { open: newState });\n setOpenState(newState);\n };\n\n // update active option based on change in open state\n React.useEffect(() => {\n if (open && !activeOption) {\n // if there is a selection, start at the most recently selected item\n if (selectedOptions.length > 0) {\n const lastSelectedOption = getOptionsMatchingValue(\n v => v === selectedOptions[selectedOptions.length - 1],\n ).pop();\n lastSelectedOption && setActiveOption(lastSelectedOption);\n }\n // default to starting at the first option\n else {\n setActiveOption(getOptionAtIndex(0));\n }\n } else if (!open) {\n // reset the active option when closing\n setActiveOption(undefined);\n }\n // this should only be run in response to changes in the open state\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n return {\n ...optionCollection,\n ...selectionState,\n activeOption,\n appearance,\n focusVisible,\n hasFocus,\n ignoreNextBlur,\n inlinePopup,\n open,\n setActiveOption,\n setFocusVisible,\n setHasFocus,\n setOpen,\n setValue,\n size,\n value,\n };\n};\n"],"sourceRoot":"../src/"}
@@ -27,11 +27,13 @@ function useComboboxPopup(props, triggerShorthand, listboxShorthand) {
27
27
  targetRef,
28
28
  containerRef
29
29
  } = react_positioning_1.usePositioning(popperOptions);
30
+ const listboxRef = react_utilities_1.useMergedRefs(listboxShorthand === null || listboxShorthand === void 0 ? void 0 : listboxShorthand.ref, containerRef);
31
+ const listbox = listboxShorthand && { ...listboxShorthand,
32
+ ref: listboxRef
33
+ };
30
34
  return [{ ...triggerShorthand,
31
35
  ref: react_utilities_1.useMergedRefs(triggerShorthand === null || triggerShorthand === void 0 ? void 0 : triggerShorthand.ref, targetRef)
32
- }, { ...listboxShorthand,
33
- ref: react_utilities_1.useMergedRefs(listboxShorthand === null || listboxShorthand === void 0 ? void 0 : listboxShorthand.ref, containerRef)
34
- }];
36
+ }, listbox];
35
37
  }
36
38
 
37
39
  exports.useComboboxPopup = useComboboxPopup;
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/useComboboxPopup.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,mBAAA,gBAAA,OAAA,CAAA,6BAAA,CAAA;;AACA,MAAA,iBAAA,gBAAA,OAAA,CAAA,2BAAA,CAAA;;AAeA,SAAgB,gBAAhB,CACE,KADF,EAEE,gBAFF,EAGE,gBAHF,EAG2D;EAEzD,MAAM;IAAE;EAAF,IAAkB,KAAxB,CAFyD,CAIzD;;EACA,MAAM,aAAa,GAAG;IACpB,QAAQ,EAAE,OADU;IAEpB,KAAK,EAAE,OAFa;IAGpB,MAAM,EAAE;MAAE,SAAS,EAAE,CAAb;MAAgB,QAAQ,EAAE;IAA1B,CAHY;IAIpB,GAAG,mBAAA,CAAA,2BAAA,CAA4B,WAA5B;EAJiB,CAAtB;EAOA,MAAM;IAAE,SAAF;IAAa;EAAb,IAA8B,mBAAA,CAAA,cAAA,CAAe,aAAf,CAApC;EAEA,OAAO,CACL,EAAE,GAAG,gBAAL;IAAuB,GAAG,EAAE,iBAAA,CAAA,aAAA,CAAc,gBAAgB,KAAA,IAAhB,IAAA,gBAAgB,KAAA,KAAA,CAAhB,GAAgB,KAAA,CAAhB,GAAA,gBAAgB,CAAE,GAAhC,EAAqC,SAArC;EAA5B,CADK,EAEL,EAAE,GAAG,gBAAL;IAAuB,GAAG,EAAE,iBAAA,CAAA,aAAA,CAAc,gBAAgB,KAAA,IAAhB,IAAA,gBAAgB,KAAA,KAAA,CAAhB,GAAgB,KAAA,CAAhB,GAAA,gBAAgB,CAAE,GAAhC,EAAqC,YAArC;EAA5B,CAFK,CAAP;AAID;;AArBD,OAAA,CAAA,gBAAA,GAAA,gBAAA","sourcesContent":["import { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport { ExtractSlotProps, Slot, useMergedRefs } from '@fluentui/react-utilities';\nimport type { ComboboxBaseProps } from './ComboboxBase.types';\nimport { Listbox } from '../components/Listbox/Listbox';\n\nexport function useComboboxPopup(\n props: ComboboxBaseProps,\n triggerShorthand?: ExtractSlotProps<Slot<'button'>>,\n listboxShorthand?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [ExtractSlotProps<Slot<'button'>>, ExtractSlotProps<Slot<typeof Listbox>>];\nexport function useComboboxPopup(\n props: ComboboxBaseProps,\n triggerShorthand?: ExtractSlotProps<Slot<'input'>>,\n listboxShorthand?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [ExtractSlotProps<Slot<'input'>>, ExtractSlotProps<Slot<typeof Listbox>>];\n\nexport function useComboboxPopup(\n props: ComboboxBaseProps,\n triggerShorthand?: ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>,\n listboxShorthand?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>, ExtractSlotProps<Slot<typeof Listbox>>] {\n const { positioning } = props;\n\n // popper options\n const popperOptions = {\n position: 'below' as const,\n align: 'start' as const,\n offset: { crossAxis: 0, mainAxis: 2 },\n ...resolvePositioningShorthand(positioning),\n };\n\n const { targetRef, containerRef } = usePositioning(popperOptions);\n\n return [\n { ...triggerShorthand, ref: useMergedRefs(triggerShorthand?.ref, targetRef) },\n { ...listboxShorthand, ref: useMergedRefs(listboxShorthand?.ref, containerRef) },\n ];\n}\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/useComboboxPopup.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,mBAAA,gBAAA,OAAA,CAAA,6BAAA,CAAA;;AACA,MAAA,iBAAA,gBAAA,OAAA,CAAA,2BAAA,CAAA;;AAeA,SAAgB,gBAAhB,CACE,KADF,EAEE,gBAFF,EAGE,gBAHF,EAG2D;EAKzD,MAAM;IAAE;EAAF,IAAkB,KAAxB,CALyD,CAOzD;;EACA,MAAM,aAAa,GAAG;IACpB,QAAQ,EAAE,OADU;IAEpB,KAAK,EAAE,OAFa;IAGpB,MAAM,EAAE;MAAE,SAAS,EAAE,CAAb;MAAgB,QAAQ,EAAE;IAA1B,CAHY;IAIpB,GAAG,mBAAA,CAAA,2BAAA,CAA4B,WAA5B;EAJiB,CAAtB;EAOA,MAAM;IAAE,SAAF;IAAa;EAAb,IAA8B,mBAAA,CAAA,cAAA,CAAe,aAAf,CAApC;EAEA,MAAM,UAAU,GAAG,iBAAA,CAAA,aAAA,CAAc,gBAAgB,KAAA,IAAhB,IAAA,gBAAgB,KAAA,KAAA,CAAhB,GAAgB,KAAA,CAAhB,GAAA,gBAAgB,CAAE,GAAhC,EAAqC,YAArC,CAAnB;EACA,MAAM,OAAO,GAAG,gBAAgB,IAAI,EAAE,GAAG,gBAAL;IAAuB,GAAG,EAAE;EAA5B,CAApC;EAEA,OAAO,CAAC,EAAE,GAAG,gBAAL;IAAuB,GAAG,EAAE,iBAAA,CAAA,aAAA,CAAc,gBAAgB,KAAA,IAAhB,IAAA,gBAAgB,KAAA,KAAA,CAAhB,GAAgB,KAAA,CAAhB,GAAA,gBAAgB,CAAE,GAAhC,EAAqC,SAArC;EAA5B,CAAD,EAAgF,OAAhF,CAAP;AACD;;AAxBD,OAAA,CAAA,gBAAA,GAAA,gBAAA","sourcesContent":["import { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport { ExtractSlotProps, Slot, useMergedRefs } from '@fluentui/react-utilities';\nimport type { ComboboxBaseProps } from './ComboboxBase.types';\nimport { Listbox } from '../components/Listbox/Listbox';\n\nexport function useComboboxPopup(\n props: ComboboxBaseProps,\n triggerShorthand?: ExtractSlotProps<Slot<'button'>>,\n listboxShorthand?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [trigger: ExtractSlotProps<Slot<'button'>>, listbox?: ExtractSlotProps<Slot<typeof Listbox>>];\nexport function useComboboxPopup(\n props: ComboboxBaseProps,\n triggerShorthand?: ExtractSlotProps<Slot<'input'>>,\n listboxShorthand?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [trigger: ExtractSlotProps<Slot<'input'>>, listbox?: ExtractSlotProps<Slot<typeof Listbox>>];\n\nexport function useComboboxPopup(\n props: ComboboxBaseProps,\n triggerShorthand?: ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>,\n listboxShorthand?: ExtractSlotProps<Slot<typeof Listbox>>,\n): [\n trigger: ExtractSlotProps<Slot<'input'>> | ExtractSlotProps<Slot<'button'>>,\n listbox?: ExtractSlotProps<Slot<typeof Listbox>>,\n] {\n const { positioning } = props;\n\n // popper options\n const popperOptions = {\n position: 'below' as const,\n align: 'start' as const,\n offset: { crossAxis: 0, mainAxis: 2 },\n ...resolvePositioningShorthand(positioning),\n };\n\n const { targetRef, containerRef } = usePositioning(popperOptions);\n\n const listboxRef = useMergedRefs(listboxShorthand?.ref, containerRef);\n const listbox = listboxShorthand && { ...listboxShorthand, ref: listboxRef };\n\n return [{ ...triggerShorthand, ref: useMergedRefs(triggerShorthand?.ref, targetRef) }, listbox];\n}\n"],"sourceRoot":"../src/"}
@@ -11,7 +11,7 @@ const useSelection = props => {
11
11
  const {
12
12
  defaultSelectedOptions,
13
13
  multiselect,
14
- onSelect
14
+ onOptionSelect
15
15
  } = props;
16
16
  const [selectedOptions, setSelectedOptions] = react_utilities_1.useControllableState({
17
17
  state: props.selectedOptions,
@@ -41,15 +41,24 @@ const useSelection = props => {
41
41
  }
42
42
 
43
43
  setSelectedOptions(newSelection);
44
- onSelect === null || onSelect === void 0 ? void 0 : onSelect(event, {
44
+ onOptionSelect === null || onOptionSelect === void 0 ? void 0 : onOptionSelect(event, {
45
45
  optionValue: option.value,
46
46
  selectedOptions: newSelection
47
47
  });
48
48
  };
49
49
 
50
+ const clearSelection = event => {
51
+ setSelectedOptions([]);
52
+ onOptionSelect === null || onOptionSelect === void 0 ? void 0 : onOptionSelect(event, {
53
+ optionValue: undefined,
54
+ selectedOptions: []
55
+ });
56
+ };
57
+
50
58
  return {
51
- selectedOptions,
52
- selectOption
59
+ clearSelection,
60
+ selectOption,
61
+ selectedOptions
53
62
  };
54
63
  };
55
64
 
@@ -1 +1 @@
1
- {"version":3,"sources":["utils/useSelection.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,iBAAA,gBAAA,OAAA,CAAA,2BAAA,CAAA;;AAIO,MAAM,YAAY,GAAI,KAAD,IAA0C;EACpE,MAAM;IAAE,sBAAF;IAA0B,WAA1B;IAAuC;EAAvC,IAAoD,KAA1D;EAEA,MAAM,CAAC,eAAD,EAAkB,kBAAlB,IAAwC,iBAAA,CAAA,oBAAA,CAAqB;IACjE,KAAK,EAAE,KAAK,CAAC,eADoD;IAEjE,YAAY,EAAE,sBAFmD;IAGjE,YAAY,EAAE;EAHmD,CAArB,CAA9C;;EAMA,MAAM,YAAY,GAAG,CAAC,KAAD,EAAyB,MAAzB,KAAgD;IACnE;IACA,IAAI,MAAM,CAAC,QAAX,EAAqB;MACnB;IACD,CAJkE,CAMnE;;;IACA,IAAI,YAAY,GAAG,CAAC,MAAM,CAAC,KAAR,CAAnB,CAPmE,CASnE;;IACA,IAAI,WAAJ,EAAiB;MACf,MAAM,aAAa,GAAG,eAAe,CAAC,SAAhB,CAA0B,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,KAA5C,CAAtB;;MACA,IAAI,aAAa,GAAG,CAAC,CAArB,EAAwB;QACtB;QACA,YAAY,GAAG,CAAC,GAAG,eAAe,CAAC,KAAhB,CAAsB,CAAtB,EAAyB,aAAzB,CAAJ,EAA6C,GAAG,eAAe,CAAC,KAAhB,CAAsB,aAAa,GAAG,CAAtC,CAAhD,CAAf;MACD,CAHD,MAGO;QACL;QACA,YAAY,GAAG,CAAC,GAAG,eAAJ,EAAqB,MAAM,CAAC,KAA5B,CAAf;MACD;IACF;;IAED,kBAAkB,CAAC,YAAD,CAAlB;IACA,QAAQ,KAAA,IAAR,IAAA,QAAQ,KAAA,KAAA,CAAR,GAAQ,KAAA,CAAR,GAAA,QAAQ,CAAG,KAAH,EAAU;MAAE,WAAW,EAAE,MAAM,CAAC,KAAtB;MAA6B,eAAe,EAAE;IAA9C,CAAV,CAAR;EACD,CAvBD;;EAyBA,OAAO;IAAE,eAAF;IAAmB;EAAnB,CAAP;AACD,CAnCM;;AAAM,OAAA,CAAA,YAAA,GAAY,YAAZ","sourcesContent":["import { useControllableState } from '@fluentui/react-utilities';\nimport { OptionValue } from './OptionCollection.types';\nimport { SelectionEvents, SelectionProps, SelectionValue } from './Selection.types';\n\nexport const useSelection = (props: SelectionProps): SelectionValue => {\n const { defaultSelectedOptions, multiselect, onSelect } = props;\n\n const [selectedOptions, setSelectedOptions] = useControllableState({\n state: props.selectedOptions,\n defaultState: defaultSelectedOptions,\n initialState: [],\n });\n\n const selectOption = (event: SelectionEvents, option: OptionValue) => {\n // if the option is disabled, do nothing\n if (option.disabled) {\n return;\n }\n\n // for single-select, always return the selected option\n let newSelection = [option.value];\n\n // toggle selected state of the option for multiselect\n if (multiselect) {\n const selectedIndex = selectedOptions.findIndex(o => o === option.value);\n if (selectedIndex > -1) {\n // deselect option\n newSelection = [...selectedOptions.slice(0, selectedIndex), ...selectedOptions.slice(selectedIndex + 1)];\n } else {\n // select option\n newSelection = [...selectedOptions, option.value];\n }\n }\n\n setSelectedOptions(newSelection);\n onSelect?.(event, { optionValue: option.value, selectedOptions: newSelection });\n };\n\n return { selectedOptions, selectOption };\n};\n"],"sourceRoot":"../src/"}
1
+ {"version":3,"sources":["utils/useSelection.ts"],"names":[],"mappings":";;;;;;;AAAA,MAAA,iBAAA,gBAAA,OAAA,CAAA,2BAAA,CAAA;;AAIO,MAAM,YAAY,GAAI,KAAD,IAA0C;EACpE,MAAM;IAAE,sBAAF;IAA0B,WAA1B;IAAuC;EAAvC,IAA0D,KAAhE;EAEA,MAAM,CAAC,eAAD,EAAkB,kBAAlB,IAAwC,iBAAA,CAAA,oBAAA,CAAqB;IACjE,KAAK,EAAE,KAAK,CAAC,eADoD;IAEjE,YAAY,EAAE,sBAFmD;IAGjE,YAAY,EAAE;EAHmD,CAArB,CAA9C;;EAMA,MAAM,YAAY,GAAG,CAAC,KAAD,EAAyB,MAAzB,KAAgD;IACnE;IACA,IAAI,MAAM,CAAC,QAAX,EAAqB;MACnB;IACD,CAJkE,CAMnE;;;IACA,IAAI,YAAY,GAAG,CAAC,MAAM,CAAC,KAAR,CAAnB,CAPmE,CASnE;;IACA,IAAI,WAAJ,EAAiB;MACf,MAAM,aAAa,GAAG,eAAe,CAAC,SAAhB,CAA0B,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,KAA5C,CAAtB;;MACA,IAAI,aAAa,GAAG,CAAC,CAArB,EAAwB;QACtB;QACA,YAAY,GAAG,CAAC,GAAG,eAAe,CAAC,KAAhB,CAAsB,CAAtB,EAAyB,aAAzB,CAAJ,EAA6C,GAAG,eAAe,CAAC,KAAhB,CAAsB,aAAa,GAAG,CAAtC,CAAhD,CAAf;MACD,CAHD,MAGO;QACL;QACA,YAAY,GAAG,CAAC,GAAG,eAAJ,EAAqB,MAAM,CAAC,KAA5B,CAAf;MACD;IACF;;IAED,kBAAkB,CAAC,YAAD,CAAlB;IACA,cAAc,KAAA,IAAd,IAAA,cAAc,KAAA,KAAA,CAAd,GAAc,KAAA,CAAd,GAAA,cAAc,CAAG,KAAH,EAAU;MAAE,WAAW,EAAE,MAAM,CAAC,KAAtB;MAA6B,eAAe,EAAE;IAA9C,CAAV,CAAd;EACD,CAvBD;;EAyBA,MAAM,cAAc,GAAI,KAAD,IAA2B;IAChD,kBAAkB,CAAC,EAAD,CAAlB;IACA,cAAc,KAAA,IAAd,IAAA,cAAc,KAAA,KAAA,CAAd,GAAc,KAAA,CAAd,GAAA,cAAc,CAAG,KAAH,EAAU;MAAE,WAAW,EAAE,SAAf;MAA0B,eAAe,EAAE;IAA3C,CAAV,CAAd;EACD,CAHD;;EAKA,OAAO;IAAE,cAAF;IAAkB,YAAlB;IAAgC;EAAhC,CAAP;AACD,CAxCM;;AAAM,OAAA,CAAA,YAAA,GAAY,YAAZ","sourcesContent":["import { useControllableState } from '@fluentui/react-utilities';\nimport { OptionValue } from './OptionCollection.types';\nimport { SelectionEvents, SelectionProps, SelectionValue } from './Selection.types';\n\nexport const useSelection = (props: SelectionProps): SelectionValue => {\n const { defaultSelectedOptions, multiselect, onOptionSelect } = props;\n\n const [selectedOptions, setSelectedOptions] = useControllableState({\n state: props.selectedOptions,\n defaultState: defaultSelectedOptions,\n initialState: [],\n });\n\n const selectOption = (event: SelectionEvents, option: OptionValue) => {\n // if the option is disabled, do nothing\n if (option.disabled) {\n return;\n }\n\n // for single-select, always return the selected option\n let newSelection = [option.value];\n\n // toggle selected state of the option for multiselect\n if (multiselect) {\n const selectedIndex = selectedOptions.findIndex(o => o === option.value);\n if (selectedIndex > -1) {\n // deselect option\n newSelection = [...selectedOptions.slice(0, selectedIndex), ...selectedOptions.slice(selectedIndex + 1)];\n } else {\n // select option\n newSelection = [...selectedOptions, option.value];\n }\n }\n\n setSelectedOptions(newSelection);\n onOptionSelect?.(event, { optionValue: option.value, selectedOptions: newSelection });\n };\n\n const clearSelection = (event: SelectionEvents) => {\n setSelectedOptions([]);\n onOptionSelect?.(event, { optionValue: undefined, selectedOptions: [] });\n };\n\n return { clearSelection, selectOption, selectedOptions };\n};\n"],"sourceRoot":"../src/"}