@fluentui-copilot/react-prompt-listbox 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.json CHANGED
@@ -2,7 +2,43 @@
2
2
  "name": "@fluentui-copilot/react-prompt-listbox",
3
3
  "entries": [
4
4
  {
5
- "date": "Tue, 23 Jul 2024 00:55:16 GMT",
5
+ "date": "Mon, 05 Aug 2024 19:36:07 GMT",
6
+ "tag": "@fluentui-copilot/react-prompt-listbox_v0.0.3",
7
+ "version": "0.0.3",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "author": "jiangemma@microsoft.com",
12
+ "package": "@fluentui-copilot/react-prompt-listbox",
13
+ "commit": "475b4c4ddc9cbe48b611c168ba65324d51d83f0d",
14
+ "comment": "feat: Remove unused multiselect prop."
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "date": "Thu, 01 Aug 2024 22:28:24 GMT",
21
+ "tag": "@fluentui-copilot/react-prompt-listbox_v0.0.2",
22
+ "version": "0.0.2",
23
+ "comments": {
24
+ "patch": [
25
+ {
26
+ "author": "estebanmu@microsoft.com",
27
+ "package": "@fluentui-copilot/react-prompt-listbox",
28
+ "commit": "34f846df4bc12151b41dc761e7edd4128714dbd8",
29
+ "comment": "feat: Make non-fluid default behavior and allow setting fluid via promptlistbox hook."
30
+ },
31
+ {
32
+ "author": "jiangemma@microsoft.com",
33
+ "package": "@fluentui-copilot/react-prompt-listbox",
34
+ "commit": "34a27b4042529f60c21b1b2ac46e7f0ab6f5274b",
35
+ "comment": "fix: Force listbox to render below the trigger"
36
+ }
37
+ ]
38
+ }
39
+ },
40
+ {
41
+ "date": "Tue, 23 Jul 2024 00:56:25 GMT",
6
42
  "tag": "@fluentui-copilot/react-prompt-listbox_v0.0.1",
7
43
  "version": "0.0.1",
8
44
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,31 @@
1
1
  # Change Log - @fluentui-copilot/react-prompt-listbox
2
2
 
3
- This log was last generated on Tue, 23 Jul 2024 00:55:16 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 05 Aug 2024 19:36:07 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [0.0.3](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.3)
8
+
9
+ Mon, 05 Aug 2024 19:36:07 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/react-prompt-listbox_v0.0.2..@fluentui-copilot/react-prompt-listbox_v0.0.3)
11
+
12
+ ### Patches
13
+
14
+ - feat: Remove unused multiselect prop. ([PR #1985](https://github.com/microsoft/fluentai/pull/1985) by jiangemma@microsoft.com)
15
+
16
+ ## [0.0.2](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.2)
17
+
18
+ Thu, 01 Aug 2024 22:28:24 GMT
19
+ [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/react-prompt-listbox_v0.0.1..@fluentui-copilot/react-prompt-listbox_v0.0.2)
20
+
21
+ ### Patches
22
+
23
+ - feat: Make non-fluid default behavior and allow setting fluid via promptlistbox hook. ([PR #1949](https://github.com/microsoft/fluentai/pull/1949) by estebanmu@microsoft.com)
24
+ - fix: Force listbox to render below the trigger ([PR #1970](https://github.com/microsoft/fluentai/pull/1970) by jiangemma@microsoft.com)
25
+
7
26
  ## [0.0.1](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.1)
8
27
 
9
- Tue, 23 Jul 2024 00:55:16 GMT
28
+ Tue, 23 Jul 2024 00:56:25 GMT
10
29
 
11
30
  ### Patches
12
31
 
package/dist/index.d.ts CHANGED
@@ -122,7 +122,7 @@ declare type PromptListboxContextValues = {
122
122
  /**
123
123
  * PromptListbox Props
124
124
  */
125
- export declare type PromptListboxProps = ComponentProps<PromptListboxSlots> & Pick<PortalProps, 'mountNode'> & OptionCollectionState & SelectionState & Pick<PromptListboxContextState, 'activeDescendantController'> & Pick<ComboboxProps, 'onActiveOptionChange'> & {
125
+ export declare type PromptListboxProps = Omit<ComponentProps<PromptListboxSlots>, 'multiselect'> & Pick<PortalProps, 'mountNode'> & OptionCollectionState & SelectionState & Pick<PromptListboxContextState, 'activeDescendantController'> & Pick<ComboboxProps, 'onActiveOptionChange'> & {
126
126
  /**
127
127
  * Whether to listbox should be rendered.
128
128
  *
@@ -256,12 +256,22 @@ export declare type UsePromptListboxFunctionalityParams = {
256
256
  open?: boolean;
257
257
  defaultOpen?: boolean;
258
258
  onOpenChange?: EventHandler<OnOpenChangeData>;
259
- onSelectionModeChange?: (isInSelectionMode: boolean) => void;
260
259
  positioning?: PositioningShorthand;
260
+ /**
261
+ * Callback to call when the selection mode (selecting an action vs typing) changes.
262
+ */
263
+ onSelectionModeChange?: (isInSelectionMode: boolean) => void;
261
264
  /**
262
265
  * Props to be passed to the ListboxComponent
263
266
  */
264
267
  listboxProps?: ProcessedPromptListboxProps;
268
+ /**
269
+ * Whether the listbox's width should take all the available space or only
270
+ * the required space.
271
+ *
272
+ * @default false
273
+ */
274
+ fluid?: boolean;
265
275
  };
266
276
 
267
277
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["PromptListbox.types.ts"],"sourcesContent":["import type { ActiveDescendantContextValue } from '@fluentui/react-aria';\nimport type {\n ComboboxProps,\n ComponentProps,\n ComponentState,\n Listbox,\n ListboxContextValue,\n PortalProps,\n Slot,\n} from '@fluentui/react-components';\nimport type { PromptListboxContextState } from './usePromptListboxContextValues';\nimport type { OptionCollectionState } from '../utils/OptionCollection.types';\nimport type { SelectionState } from '../utils/Selection.types';\n\nexport type PromptListboxSlots = {\n root: Slot<typeof Listbox>;\n};\n\n/**\n * PromptListbox Props\n */\nexport type PromptListboxProps = ComponentProps<PromptListboxSlots> &\n Pick<PortalProps, 'mountNode'> &\n OptionCollectionState &\n SelectionState &\n Pick<PromptListboxContextState, 'activeDescendantController'> &\n Pick<ComboboxProps, 'onActiveOptionChange'> & {\n /**\n * Whether to listbox should be rendered.\n *\n * @default false\n */\n open?: boolean;\n /**\n * Whether to render the listbox inline or in a portal.\n *\n * @default false\n */\n inlinePopup?: boolean;\n };\n\n/**\n * State used in rendering PromptListbox\n */\nexport type PromptListboxState = ComponentState<PromptListboxSlots> &\n PromptListboxContextState &\n Required<Pick<PromptListboxProps, 'open' | 'inlinePopup'>> &\n Pick<PromptListboxProps, 'mountNode'>;\n\nexport type PromptListboxContextValues = {\n listbox: ListboxContextValue;\n activeDescendant: ActiveDescendantContextValue;\n};\n"],"names":[],"rangeMappings":"","mappings":"AAiDA,WAGE"}
1
+ {"version":3,"sources":["PromptListbox.types.ts"],"sourcesContent":["import type { ActiveDescendantContextValue } from '@fluentui/react-aria';\nimport type {\n ComboboxProps,\n ComponentProps,\n ComponentState,\n Listbox,\n ListboxContextValue,\n PortalProps,\n Slot,\n} from '@fluentui/react-components';\nimport type { PromptListboxContextState } from './usePromptListboxContextValues';\nimport type { OptionCollectionState } from '../utils/OptionCollection.types';\nimport type { SelectionState } from '../utils/Selection.types';\n\nexport type PromptListboxSlots = {\n root: Slot<typeof Listbox>;\n};\n\n/**\n * PromptListbox Props\n */\nexport type PromptListboxProps = Omit<ComponentProps<PromptListboxSlots>, 'multiselect'> &\n Pick<PortalProps, 'mountNode'> &\n OptionCollectionState &\n SelectionState &\n Pick<PromptListboxContextState, 'activeDescendantController'> &\n Pick<ComboboxProps, 'onActiveOptionChange'> & {\n /**\n * Whether to listbox should be rendered.\n *\n * @default false\n */\n open?: boolean;\n /**\n * Whether to render the listbox inline or in a portal.\n *\n * @default false\n */\n inlinePopup?: boolean;\n };\n\n/**\n * State used in rendering PromptListbox\n */\nexport type PromptListboxState = ComponentState<PromptListboxSlots> &\n PromptListboxContextState &\n Required<Pick<PromptListboxProps, 'open' | 'inlinePopup'>> &\n Pick<PromptListboxProps, 'mountNode'>;\n\nexport type PromptListboxContextValues = {\n listbox: ListboxContextValue;\n activeDescendant: ActiveDescendantContextValue;\n};\n"],"names":[],"rangeMappings":"","mappings":"AAiDA,WAGE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["PromptListboxFunctionality.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { PromptListboxProps } from '../../components/PromptListbox';\nimport type { PositioningShorthand } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\n\n// Note: While we are removing multiselect, we are keeping the logic and disabling it\n// in case it's needed in the future.\nexport type ProcessedPromptListboxProps = Partial<\n Omit<PromptListboxProps, 'activeDescendantController' | 'multiselect'>\n> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: React.MutableRefObject<any>;\n};\n\nexport type UsePromptListboxFunctionality = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSX.Element;\n /**\n * Props to be spread in the PromptInput, these props are needed for the keyboard behavior to\n * work correctly.\n */\n triggerProps: {\n ref: React.RefObject<HTMLSpanElement>;\n /**\n * Whether the listbox is being used to go through options or the user is currently typing.\n */\n isInSelectionMode: boolean;\n } & Required<Pick<EditorInputProps, 'onBlur' | 'onFocus' | 'onKeyDown'>>;\n /**\n * Ref used to point which element the listbox should be anchored to. Most use cases\n * will provide this prop to the PromptInput's EditorInput (since this is the root slot,\n * this is provided directly to the component and not the slot).\n *\n * Note: If the containerRef is the same as the trigger, the ref provided in triggerProps needs\n * to be merged with this one using `useMergedRefs(containerRef, triggerProps.ref);`\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n containerRef: React.MutableRefObject<any>;\n /**\n * Plugin used to tell where the cursor is in the EditorInput, this is important for the\n * keyboard behavior. This should be passed as children in the PromptInput.\n */\n cursorPositionPlugin: JSX.Element;\n};\n\nexport type UsePromptListboxFunctionalityParams = {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n onSelectionModeChange?: (isInSelectionMode: boolean) => void;\n positioning?: PositioningShorthand;\n /**\n * Props to be passed to the ListboxComponent\n */\n listboxProps?: ProcessedPromptListboxProps;\n};\n\nexport type OnOpenChangeData = (\n | EventData<'click', React.MouseEvent<HTMLSpanElement>>\n | EventData<'focus', React.FocusEvent<HTMLSpanElement>>\n | EventData<'keyboard', React.KeyboardEvent<HTMLSpanElement>>\n) & {\n open: boolean;\n};\n"],"names":[],"rangeMappings":"","mappings":"AA4DA,WAME"}
1
+ {"version":3,"sources":["PromptListboxFunctionality.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { PromptListboxProps } from '../../components/PromptListbox';\nimport type { PositioningShorthand } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\n\n// Note: While we are removing multiselect, we are keeping the logic and disabling it\n// in case it's needed in the future.\nexport type ProcessedPromptListboxProps = Partial<\n Omit<PromptListboxProps, 'activeDescendantController' | 'multiselect'>\n> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: React.MutableRefObject<any>;\n};\n\nexport type UsePromptListboxFunctionality = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSX.Element;\n /**\n * Props to be spread in the PromptInput, these props are needed for the keyboard behavior to\n * work correctly.\n */\n triggerProps: {\n ref: React.RefObject<HTMLSpanElement>;\n /**\n * Whether the listbox is being used to go through options or the user is currently typing.\n */\n isInSelectionMode: boolean;\n } & Required<Pick<EditorInputProps, 'onBlur' | 'onFocus' | 'onKeyDown'>>;\n /**\n * Ref used to point which element the listbox should be anchored to. Most use cases\n * will provide this prop to the PromptInput's EditorInput (since this is the root slot,\n * this is provided directly to the component and not the slot).\n *\n * Note: If the containerRef is the same as the trigger, the ref provided in triggerProps needs\n * to be merged with this one using `useMergedRefs(containerRef, triggerProps.ref);`\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n containerRef: React.MutableRefObject<any>;\n /**\n * Plugin used to tell where the cursor is in the EditorInput, this is important for the\n * keyboard behavior. This should be passed as children in the PromptInput.\n */\n cursorPositionPlugin: JSX.Element;\n};\n\nexport type UsePromptListboxFunctionalityParams = {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n positioning?: PositioningShorthand;\n\n /**\n * Callback to call when the selection mode (selecting an action vs typing) changes.\n */\n onSelectionModeChange?: (isInSelectionMode: boolean) => void;\n\n /**\n * Props to be passed to the ListboxComponent\n */\n listboxProps?: ProcessedPromptListboxProps;\n\n /**\n * Whether the listbox's width should take all the available space or only\n * the required space.\n *\n * @default false\n */\n fluid?: boolean;\n};\n\nexport type OnOpenChangeData = (\n | EventData<'click', React.MouseEvent<HTMLSpanElement>>\n | EventData<'focus', React.FocusEvent<HTMLSpanElement>>\n | EventData<'keyboard', React.KeyboardEvent<HTMLSpanElement>>\n) & {\n open: boolean;\n};\n"],"names":[],"rangeMappings":"","mappings":"AAyEA,WAME"}
@@ -2,8 +2,10 @@
2
2
  import { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';
3
3
  export function useComboboxPositioning(props) {
4
4
  const {
5
- positioning
5
+ positioning,
6
+ fluid
6
7
  } = props;
8
+ const fallbackPositions = ['below'];
7
9
  // popper options
8
10
  const popperOptions = {
9
11
  position: 'below',
@@ -12,8 +14,8 @@ export function useComboboxPositioning(props) {
12
14
  crossAxis: 0,
13
15
  mainAxis: 2
14
16
  },
15
- fallbackPositions: [],
16
- matchTargetSize: 'width',
17
+ fallbackPositions: fallbackPositions,
18
+ matchTargetSize: fluid ? 'width' : undefined,
17
19
  ...resolvePositioningShorthand(positioning)
18
20
  };
19
21
  const {
@@ -1 +1 @@
1
- {"version":3,"sources":["useComboboxPositioning.ts"],"sourcesContent":["// Brought from Fluent UI\n\nimport { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport type * as React from 'react';\nimport type { ComboboxBaseProps } from '@fluentui/react-combobox';\n\nexport function useComboboxPositioning(props: ComboboxBaseProps): [\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n listboxRef: React.MutableRefObject<any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n triggerRef: React.MutableRefObject<any>,\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 fallbackPositions: [],\n matchTargetSize: 'width' as const,\n ...resolvePositioningShorthand(positioning),\n };\n\n const { targetRef, containerRef } = usePositioning(popperOptions);\n\n return [containerRef, targetRef];\n}\n"],"names":["resolvePositioningShorthand","usePositioning","useComboboxPositioning","props","positioning","popperOptions","position","align","offset","crossAxis","mainAxis","fallbackPositions","matchTargetSize","targetRef","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,yBAAyB;AAEzB,SAASA,2BAA2B,EAAEC,cAAc,QAAQ,8BAA8B;AAI1F,OAAO,SAASC,uBAAuBC,KAAwB;IAM7D,MAAM,EAAEC,WAAW,EAAE,GAAGD;IAExB,iBAAiB;IACjB,MAAME,gBAAgB;QACpBC,UAAU;QACVC,OAAO;QACPC,QAAQ;YAAEC,WAAW;YAAGC,UAAU;QAAE;QACpCC,mBAAmB,EAAE;QACrBC,iBAAiB;QACjB,GAAGZ,4BAA4BI,YAAY;IAC7C;IAEA,MAAM,EAAES,SAAS,EAAEC,YAAY,EAAE,GAAGb,eAAeI;IAEnD,OAAO;QAACS;QAAcD;KAAU;AAClC"}
1
+ {"version":3,"sources":["useComboboxPositioning.ts"],"sourcesContent":["// Brought from Fluent UI\n\nimport { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport type * as React from 'react';\nimport type { ComboboxBaseProps } from '@fluentui/react-combobox';\nimport type { UsePromptListboxFunctionalityParams } from './PromptListboxFunctionality.types';\nimport type { PositioningShorthandValue } from '@fluentui/react-positioning';\n\nexport function useComboboxPositioning(\n props: ComboboxBaseProps & Required<Pick<UsePromptListboxFunctionalityParams, 'fluid'>>,\n): [\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n listboxRef: React.MutableRefObject<any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n triggerRef: React.MutableRefObject<any>,\n] {\n const { positioning, fluid } = props;\n\n const fallbackPositions: PositioningShorthandValue[] = ['below'];\n\n // popper options\n const popperOptions = {\n position: 'below' as const,\n align: 'start' as const,\n offset: { crossAxis: 0, mainAxis: 2 },\n fallbackPositions: fallbackPositions,\n matchTargetSize: fluid ? ('width' as const) : undefined,\n ...resolvePositioningShorthand(positioning),\n };\n\n const { targetRef, containerRef } = usePositioning(popperOptions);\n\n return [containerRef, targetRef];\n}\n"],"names":["resolvePositioningShorthand","usePositioning","useComboboxPositioning","props","positioning","fluid","fallbackPositions","popperOptions","position","align","offset","crossAxis","mainAxis","matchTargetSize","undefined","targetRef","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,yBAAyB;AAEzB,SAASA,2BAA2B,EAAEC,cAAc,QAAQ,8BAA8B;AAM1F,OAAO,SAASC,uBACdC,KAAuF;IAOvF,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAE,GAAGF;IAE/B,MAAMG,oBAAiD;QAAC;KAAQ;IAEhE,iBAAiB;IACjB,MAAMC,gBAAgB;QACpBC,UAAU;QACVC,OAAO;QACPC,QAAQ;YAAEC,WAAW;YAAGC,UAAU;QAAE;QACpCN,mBAAmBA;QACnBO,iBAAiBR,QAAS,UAAoBS;QAC9C,GAAGd,4BAA4BI,YAAY;IAC7C;IAEA,MAAM,EAAEW,SAAS,EAAEC,YAAY,EAAE,GAAGf,eAAeM;IAEnD,OAAO;QAACS;QAAcD;KAAU;AAClC"}
@@ -15,7 +15,8 @@ export function usePromptListboxFunctionality(params) {
15
15
  positioning,
16
16
  onOpenChange,
17
17
  onSelectionModeChange,
18
- listboxProps
18
+ listboxProps,
19
+ fluid = false
19
20
  } = params;
20
21
  const {
21
22
  listboxRef: activeDescendantListboxRef,
@@ -114,7 +115,8 @@ export function usePromptListboxFunctionality(params) {
114
115
  // eslint-disable-next-line react-hooks/exhaustive-deps
115
116
  }, [hideActiveDescendant]);
116
117
  const [comboboxPopupRef, comboboxTargetRef] = useComboboxPositioning({
117
- positioning
118
+ positioning,
119
+ fluid
118
120
  });
119
121
  const listboxMergedRef = useMergedRefs(comboboxPopupRef, activeDescendantListboxRef, listboxProps === null || listboxProps === void 0 ? void 0 : listboxProps.ref);
120
122
  const listbox = React.useMemo(() => {
@@ -1 +1 @@
1
- {"version":3,"sources":["usePromptListboxFunctionality.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useActiveDescendant } from '@fluentui/react-aria';\nimport { mergeCallbacks, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport { TextCursorPositionPlugin } from '../../plugins/TextCursorPositionPlugin';\nimport { useOptionCollection } from './useOptionCollection';\nimport { useSelection } from './useSelection';\nimport { ArrowDown, ArrowLeft, ArrowRight, ArrowUp } from '@fluentui/keyboard-keys';\nimport { useComboboxPositioning } from './useComboboxPositioning';\nimport { useTriggerKeydown } from './useTriggerKeyDown';\nimport { PromptListbox } from '../PromptListbox';\nimport { promptOptionClassNames } from '../PromptOption';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\nimport type {\n UsePromptListboxFunctionalityParams,\n UsePromptListboxFunctionality,\n} from './PromptListboxFunctionality.types';\n\nexport function usePromptListboxFunctionality(\n params: UsePromptListboxFunctionalityParams,\n): UsePromptListboxFunctionality {\n const { positioning, onOpenChange, onSelectionModeChange, listboxProps } = params;\n const {\n listboxRef: activeDescendantListboxRef,\n activeParentRef,\n controller: activeDescendantController,\n } = useActiveDescendant<HTMLSpanElement, HTMLDivElement>({\n matchOption: el => el.classList.contains(promptOptionClassNames.root),\n });\n // useMergedRefs to normalize the ref into a React.RefObject type\n const triggerRef = useMergedRefs(activeParentRef);\n const selectionState = useSelection(listboxProps ?? {});\n const { selectOption } = selectionState;\n const optionCollection = useOptionCollection();\n const { getOptionById } = optionCollection;\n const [isInLastPosition, setIsInLastPosition] = React.useState(true);\n const [isInSelectionMode, setIsInSelectionMode] = React.useState(false);\n const [open, setOpen] = useControllableState({\n state: params.open,\n defaultState: params.defaultOpen,\n initialState: false,\n });\n\n const onBlur = (event: React.FocusEvent<HTMLSpanElement>) => {\n setOpen(false);\n onOpenChange?.(event, { event, type: 'focus', open: false });\n };\n\n const onFocus = (event: React.FocusEvent<HTMLSpanElement>) => {\n if (event.target === event.currentTarget) {\n setOpen(true);\n onOpenChange?.(event, { event, type: 'focus', open: true });\n }\n };\n\n const cursorPositionPlugin = <TextCursorPositionPlugin setIsInLastPosition={setIsInLastPosition} />;\n\n const onListboxBlur = React.useCallback(() => {\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n }, [onSelectionModeChange]);\n\n // handle combobox keyboard interaction\n const onKeyDown = useTriggerKeydown({\n ...optionCollection,\n activeDescendantController,\n getOptionById,\n onBlur: onListboxBlur,\n selectOption,\n isInLastPosition,\n open,\n multiselect: false,\n });\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n /**\n * Freeform combobox should not select\n */\n const onInputTriggerKeyDown: EditorInputProps['onKeyDown'] = useEventCallback(event => {\n // update typing state to true if the user is typing\n const action = getDropdownActionFromKey(event, { open, multiselect: false, isInLastPosition });\n if (\n event.key === ArrowLeft ||\n event.key === ArrowRight ||\n (!isInLastPosition && (event.key === ArrowDown || event.key === ArrowUp)) ||\n (action === 'Type' && isInLastPosition) ||\n action === 'Type'\n ) {\n activeDescendantController.blur();\n setHideActiveDescendant(true);\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n } else if (\n action === 'Next' ||\n action === 'Previous' ||\n action === 'First' ||\n action === 'Last' ||\n action === 'PageUp' ||\n action === 'PageDown'\n ) {\n setHideActiveDescendant(false);\n setIsInSelectionMode(true);\n onSelectionModeChange?.(true);\n }\n });\n\n React.useEffect(() => {\n if (hideActiveDescendant) {\n triggerRef.current?.removeAttribute('aria-activedescendant');\n }\n // We only want to run this when the hideActiveDescendant changes, if the triggerRef\n // is undefined, there's no need to remove theAttribute and we shouldn't be adding\n // refs as dependencies since it can blow up the number of runs.\n // eslint-disable-next-line react-compiler/react-compiler\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hideActiveDescendant]);\n\n const [comboboxPopupRef, comboboxTargetRef] = useComboboxPositioning({ positioning });\n\n const listboxMergedRef = useMergedRefs(comboboxPopupRef, activeDescendantListboxRef, listboxProps?.ref);\n const listbox = React.useMemo(() => {\n return (\n <PromptListbox\n open={open}\n {...listboxProps}\n {...optionCollection}\n {...selectionState}\n ref={listboxMergedRef}\n activeDescendantController={activeDescendantController}\n />\n );\n }, [activeDescendantController, listboxMergedRef, listboxProps, open, optionCollection, selectionState]);\n\n return {\n promptListbox: listbox,\n triggerProps: {\n ref: triggerRef,\n onBlur,\n onFocus,\n onKeyDown: useEventCallback(mergeCallbacks(onKeyDown, onInputTriggerKeyDown)),\n isInSelectionMode,\n },\n containerRef: comboboxTargetRef,\n cursorPositionPlugin,\n };\n}\n"],"names":["React","useActiveDescendant","mergeCallbacks","useControllableState","useEventCallback","useMergedRefs","getDropdownActionFromKey","TextCursorPositionPlugin","useOptionCollection","useSelection","ArrowDown","ArrowLeft","ArrowRight","ArrowUp","useComboboxPositioning","useTriggerKeydown","PromptListbox","promptOptionClassNames","usePromptListboxFunctionality","params","positioning","onOpenChange","onSelectionModeChange","listboxProps","listboxRef","activeDescendantListboxRef","activeParentRef","controller","activeDescendantController","matchOption","el","classList","contains","root","triggerRef","selectionState","selectOption","optionCollection","getOptionById","isInLastPosition","setIsInLastPosition","useState","isInSelectionMode","setIsInSelectionMode","open","setOpen","state","defaultState","defaultOpen","initialState","onBlur","event","type","onFocus","target","currentTarget","cursorPositionPlugin","onListboxBlur","useCallback","onKeyDown","multiselect","hideActiveDescendant","setHideActiveDescendant","onInputTriggerKeyDown","action","key","blur","useEffect","current","removeAttribute","comboboxPopupRef","comboboxTargetRef","listboxMergedRef","ref","listbox","useMemo","promptListbox","triggerProps","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["usePromptListboxFunctionality.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useActiveDescendant } from '@fluentui/react-aria';\nimport { mergeCallbacks, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport { TextCursorPositionPlugin } from '../../plugins/TextCursorPositionPlugin';\nimport { useOptionCollection } from './useOptionCollection';\nimport { useSelection } from './useSelection';\nimport { ArrowDown, ArrowLeft, ArrowRight, ArrowUp } from '@fluentui/keyboard-keys';\nimport { useComboboxPositioning } from './useComboboxPositioning';\nimport { useTriggerKeydown } from './useTriggerKeyDown';\nimport { PromptListbox } from '../PromptListbox';\nimport { promptOptionClassNames } from '../PromptOption';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\nimport type {\n UsePromptListboxFunctionalityParams,\n UsePromptListboxFunctionality,\n} from './PromptListboxFunctionality.types';\n\nexport function usePromptListboxFunctionality(\n params: UsePromptListboxFunctionalityParams,\n): UsePromptListboxFunctionality {\n const { positioning, onOpenChange, onSelectionModeChange, listboxProps, fluid = false } = params;\n const {\n listboxRef: activeDescendantListboxRef,\n activeParentRef,\n controller: activeDescendantController,\n } = useActiveDescendant<HTMLSpanElement, HTMLDivElement>({\n matchOption: el => el.classList.contains(promptOptionClassNames.root),\n });\n // useMergedRefs to normalize the ref into a React.RefObject type\n const triggerRef = useMergedRefs(activeParentRef);\n const selectionState = useSelection(listboxProps ?? {});\n const { selectOption } = selectionState;\n const optionCollection = useOptionCollection();\n const { getOptionById } = optionCollection;\n const [isInLastPosition, setIsInLastPosition] = React.useState(true);\n const [isInSelectionMode, setIsInSelectionMode] = React.useState(false);\n const [open, setOpen] = useControllableState({\n state: params.open,\n defaultState: params.defaultOpen,\n initialState: false,\n });\n\n const onBlur = (event: React.FocusEvent<HTMLSpanElement>) => {\n setOpen(false);\n onOpenChange?.(event, { event, type: 'focus', open: false });\n };\n\n const onFocus = (event: React.FocusEvent<HTMLSpanElement>) => {\n if (event.target === event.currentTarget) {\n setOpen(true);\n onOpenChange?.(event, { event, type: 'focus', open: true });\n }\n };\n\n const cursorPositionPlugin = <TextCursorPositionPlugin setIsInLastPosition={setIsInLastPosition} />;\n\n const onListboxBlur = React.useCallback(() => {\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n }, [onSelectionModeChange]);\n\n // handle combobox keyboard interaction\n const onKeyDown = useTriggerKeydown({\n ...optionCollection,\n activeDescendantController,\n getOptionById,\n onBlur: onListboxBlur,\n selectOption,\n isInLastPosition,\n open,\n multiselect: false,\n });\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n /**\n * Freeform combobox should not select\n */\n const onInputTriggerKeyDown: EditorInputProps['onKeyDown'] = useEventCallback(event => {\n // update typing state to true if the user is typing\n const action = getDropdownActionFromKey(event, { open, multiselect: false, isInLastPosition });\n if (\n event.key === ArrowLeft ||\n event.key === ArrowRight ||\n (!isInLastPosition && (event.key === ArrowDown || event.key === ArrowUp)) ||\n (action === 'Type' && isInLastPosition) ||\n action === 'Type'\n ) {\n activeDescendantController.blur();\n setHideActiveDescendant(true);\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n } else if (\n action === 'Next' ||\n action === 'Previous' ||\n action === 'First' ||\n action === 'Last' ||\n action === 'PageUp' ||\n action === 'PageDown'\n ) {\n setHideActiveDescendant(false);\n setIsInSelectionMode(true);\n onSelectionModeChange?.(true);\n }\n });\n\n React.useEffect(() => {\n if (hideActiveDescendant) {\n triggerRef.current?.removeAttribute('aria-activedescendant');\n }\n // We only want to run this when the hideActiveDescendant changes, if the triggerRef\n // is undefined, there's no need to remove theAttribute and we shouldn't be adding\n // refs as dependencies since it can blow up the number of runs.\n // eslint-disable-next-line react-compiler/react-compiler\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hideActiveDescendant]);\n\n const [comboboxPopupRef, comboboxTargetRef] = useComboboxPositioning({ positioning, fluid });\n\n const listboxMergedRef = useMergedRefs(comboboxPopupRef, activeDescendantListboxRef, listboxProps?.ref);\n const listbox = React.useMemo(() => {\n return (\n <PromptListbox\n open={open}\n {...listboxProps}\n {...optionCollection}\n {...selectionState}\n ref={listboxMergedRef}\n activeDescendantController={activeDescendantController}\n />\n );\n }, [activeDescendantController, listboxMergedRef, listboxProps, open, optionCollection, selectionState]);\n\n return {\n promptListbox: listbox,\n triggerProps: {\n ref: triggerRef,\n onBlur,\n onFocus,\n onKeyDown: useEventCallback(mergeCallbacks(onKeyDown, onInputTriggerKeyDown)),\n isInSelectionMode,\n },\n containerRef: comboboxTargetRef,\n cursorPositionPlugin,\n };\n}\n"],"names":["React","useActiveDescendant","mergeCallbacks","useControllableState","useEventCallback","useMergedRefs","getDropdownActionFromKey","TextCursorPositionPlugin","useOptionCollection","useSelection","ArrowDown","ArrowLeft","ArrowRight","ArrowUp","useComboboxPositioning","useTriggerKeydown","PromptListbox","promptOptionClassNames","usePromptListboxFunctionality","params","positioning","onOpenChange","onSelectionModeChange","listboxProps","fluid","listboxRef","activeDescendantListboxRef","activeParentRef","controller","activeDescendantController","matchOption","el","classList","contains","root","triggerRef","selectionState","selectOption","optionCollection","getOptionById","isInLastPosition","setIsInLastPosition","useState","isInSelectionMode","setIsInSelectionMode","open","setOpen","state","defaultState","defaultOpen","initialState","onBlur","event","type","onFocus","target","currentTarget","cursorPositionPlugin","onListboxBlur","useCallback","onKeyDown","multiselect","hideActiveDescendant","setHideActiveDescendant","onInputTriggerKeyDown","action","key","blur","useEffect","current","removeAttribute","comboboxPopupRef","comboboxTargetRef","listboxMergedRef","ref","listbox","useMemo","promptListbox","triggerProps","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["PromptListbox.types.ts"],"sourcesContent":["import type { ActiveDescendantContextValue } from '@fluentui/react-aria';\nimport type {\n ComboboxProps,\n ComponentProps,\n ComponentState,\n Listbox,\n ListboxContextValue,\n PortalProps,\n Slot,\n} from '@fluentui/react-components';\nimport type { PromptListboxContextState } from './usePromptListboxContextValues';\nimport type { OptionCollectionState } from '../utils/OptionCollection.types';\nimport type { SelectionState } from '../utils/Selection.types';\n\nexport type PromptListboxSlots = {\n root: Slot<typeof Listbox>;\n};\n\n/**\n * PromptListbox Props\n */\nexport type PromptListboxProps = ComponentProps<PromptListboxSlots> &\n Pick<PortalProps, 'mountNode'> &\n OptionCollectionState &\n SelectionState &\n Pick<PromptListboxContextState, 'activeDescendantController'> &\n Pick<ComboboxProps, 'onActiveOptionChange'> & {\n /**\n * Whether to listbox should be rendered.\n *\n * @default false\n */\n open?: boolean;\n /**\n * Whether to render the listbox inline or in a portal.\n *\n * @default false\n */\n inlinePopup?: boolean;\n };\n\n/**\n * State used in rendering PromptListbox\n */\nexport type PromptListboxState = ComponentState<PromptListboxSlots> &\n PromptListboxContextState &\n Required<Pick<PromptListboxProps, 'open' | 'inlinePopup'>> &\n Pick<PromptListboxProps, 'mountNode'>;\n\nexport type PromptListboxContextValues = {\n listbox: ListboxContextValue;\n activeDescendant: ActiveDescendantContextValue;\n};\n"],"names":[],"rangeMappings":"","mappings":""}
1
+ {"version":3,"sources":["PromptListbox.types.ts"],"sourcesContent":["import type { ActiveDescendantContextValue } from '@fluentui/react-aria';\nimport type {\n ComboboxProps,\n ComponentProps,\n ComponentState,\n Listbox,\n ListboxContextValue,\n PortalProps,\n Slot,\n} from '@fluentui/react-components';\nimport type { PromptListboxContextState } from './usePromptListboxContextValues';\nimport type { OptionCollectionState } from '../utils/OptionCollection.types';\nimport type { SelectionState } from '../utils/Selection.types';\n\nexport type PromptListboxSlots = {\n root: Slot<typeof Listbox>;\n};\n\n/**\n * PromptListbox Props\n */\nexport type PromptListboxProps = Omit<ComponentProps<PromptListboxSlots>, 'multiselect'> &\n Pick<PortalProps, 'mountNode'> &\n OptionCollectionState &\n SelectionState &\n Pick<PromptListboxContextState, 'activeDescendantController'> &\n Pick<ComboboxProps, 'onActiveOptionChange'> & {\n /**\n * Whether to listbox should be rendered.\n *\n * @default false\n */\n open?: boolean;\n /**\n * Whether to render the listbox inline or in a portal.\n *\n * @default false\n */\n inlinePopup?: boolean;\n };\n\n/**\n * State used in rendering PromptListbox\n */\nexport type PromptListboxState = ComponentState<PromptListboxSlots> &\n PromptListboxContextState &\n Required<Pick<PromptListboxProps, 'open' | 'inlinePopup'>> &\n Pick<PromptListboxProps, 'mountNode'>;\n\nexport type PromptListboxContextValues = {\n listbox: ListboxContextValue;\n activeDescendant: ActiveDescendantContextValue;\n};\n"],"names":[],"rangeMappings":"","mappings":""}
@@ -1 +1 @@
1
- {"version":3,"sources":["PromptListboxFunctionality.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { PromptListboxProps } from '../../components/PromptListbox';\nimport type { PositioningShorthand } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\n\n// Note: While we are removing multiselect, we are keeping the logic and disabling it\n// in case it's needed in the future.\nexport type ProcessedPromptListboxProps = Partial<\n Omit<PromptListboxProps, 'activeDescendantController' | 'multiselect'>\n> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: React.MutableRefObject<any>;\n};\n\nexport type UsePromptListboxFunctionality = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSX.Element;\n /**\n * Props to be spread in the PromptInput, these props are needed for the keyboard behavior to\n * work correctly.\n */\n triggerProps: {\n ref: React.RefObject<HTMLSpanElement>;\n /**\n * Whether the listbox is being used to go through options or the user is currently typing.\n */\n isInSelectionMode: boolean;\n } & Required<Pick<EditorInputProps, 'onBlur' | 'onFocus' | 'onKeyDown'>>;\n /**\n * Ref used to point which element the listbox should be anchored to. Most use cases\n * will provide this prop to the PromptInput's EditorInput (since this is the root slot,\n * this is provided directly to the component and not the slot).\n *\n * Note: If the containerRef is the same as the trigger, the ref provided in triggerProps needs\n * to be merged with this one using `useMergedRefs(containerRef, triggerProps.ref);`\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n containerRef: React.MutableRefObject<any>;\n /**\n * Plugin used to tell where the cursor is in the EditorInput, this is important for the\n * keyboard behavior. This should be passed as children in the PromptInput.\n */\n cursorPositionPlugin: JSX.Element;\n};\n\nexport type UsePromptListboxFunctionalityParams = {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n onSelectionModeChange?: (isInSelectionMode: boolean) => void;\n positioning?: PositioningShorthand;\n /**\n * Props to be passed to the ListboxComponent\n */\n listboxProps?: ProcessedPromptListboxProps;\n};\n\nexport type OnOpenChangeData = (\n | EventData<'click', React.MouseEvent<HTMLSpanElement>>\n | EventData<'focus', React.FocusEvent<HTMLSpanElement>>\n | EventData<'keyboard', React.KeyboardEvent<HTMLSpanElement>>\n) & {\n open: boolean;\n};\n"],"names":[],"rangeMappings":"","mappings":""}
1
+ {"version":3,"sources":["PromptListboxFunctionality.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { PromptListboxProps } from '../../components/PromptListbox';\nimport type { PositioningShorthand } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\n\n// Note: While we are removing multiselect, we are keeping the logic and disabling it\n// in case it's needed in the future.\nexport type ProcessedPromptListboxProps = Partial<\n Omit<PromptListboxProps, 'activeDescendantController' | 'multiselect'>\n> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: React.MutableRefObject<any>;\n};\n\nexport type UsePromptListboxFunctionality = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSX.Element;\n /**\n * Props to be spread in the PromptInput, these props are needed for the keyboard behavior to\n * work correctly.\n */\n triggerProps: {\n ref: React.RefObject<HTMLSpanElement>;\n /**\n * Whether the listbox is being used to go through options or the user is currently typing.\n */\n isInSelectionMode: boolean;\n } & Required<Pick<EditorInputProps, 'onBlur' | 'onFocus' | 'onKeyDown'>>;\n /**\n * Ref used to point which element the listbox should be anchored to. Most use cases\n * will provide this prop to the PromptInput's EditorInput (since this is the root slot,\n * this is provided directly to the component and not the slot).\n *\n * Note: If the containerRef is the same as the trigger, the ref provided in triggerProps needs\n * to be merged with this one using `useMergedRefs(containerRef, triggerProps.ref);`\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n containerRef: React.MutableRefObject<any>;\n /**\n * Plugin used to tell where the cursor is in the EditorInput, this is important for the\n * keyboard behavior. This should be passed as children in the PromptInput.\n */\n cursorPositionPlugin: JSX.Element;\n};\n\nexport type UsePromptListboxFunctionalityParams = {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n positioning?: PositioningShorthand;\n\n /**\n * Callback to call when the selection mode (selecting an action vs typing) changes.\n */\n onSelectionModeChange?: (isInSelectionMode: boolean) => void;\n\n /**\n * Props to be passed to the ListboxComponent\n */\n listboxProps?: ProcessedPromptListboxProps;\n\n /**\n * Whether the listbox's width should take all the available space or only\n * the required space.\n *\n * @default false\n */\n fluid?: boolean;\n};\n\nexport type OnOpenChangeData = (\n | EventData<'click', React.MouseEvent<HTMLSpanElement>>\n | EventData<'focus', React.FocusEvent<HTMLSpanElement>>\n | EventData<'keyboard', React.KeyboardEvent<HTMLSpanElement>>\n) & {\n open: boolean;\n};\n"],"names":[],"rangeMappings":"","mappings":""}
@@ -11,7 +11,10 @@ Object.defineProperty(exports, "useComboboxPositioning", {
11
11
  });
12
12
  const _reactpositioning = require("@fluentui/react-positioning");
13
13
  function useComboboxPositioning(props) {
14
- const { positioning } = props;
14
+ const { positioning, fluid } = props;
15
+ const fallbackPositions = [
16
+ 'below'
17
+ ];
15
18
  // popper options
16
19
  const popperOptions = {
17
20
  position: 'below',
@@ -20,8 +23,8 @@ function useComboboxPositioning(props) {
20
23
  crossAxis: 0,
21
24
  mainAxis: 2
22
25
  },
23
- fallbackPositions: [],
24
- matchTargetSize: 'width',
26
+ fallbackPositions: fallbackPositions,
27
+ matchTargetSize: fluid ? 'width' : undefined,
25
28
  ...(0, _reactpositioning.resolvePositioningShorthand)(positioning)
26
29
  };
27
30
  const { targetRef, containerRef } = (0, _reactpositioning.usePositioning)(popperOptions);
@@ -1 +1 @@
1
- {"version":3,"sources":["useComboboxPositioning.ts"],"sourcesContent":["// Brought from Fluent UI\n\nimport { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport type * as React from 'react';\nimport type { ComboboxBaseProps } from '@fluentui/react-combobox';\n\nexport function useComboboxPositioning(props: ComboboxBaseProps): [\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n listboxRef: React.MutableRefObject<any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n triggerRef: React.MutableRefObject<any>,\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 fallbackPositions: [],\n matchTargetSize: 'width' as const,\n ...resolvePositioningShorthand(positioning),\n };\n\n const { targetRef, containerRef } = usePositioning(popperOptions);\n\n return [containerRef, targetRef];\n}\n"],"names":["useComboboxPositioning","props","positioning","align","offset","mainAxis","fallbackPositions","resolvePositioningShorthand","matchTargetSize","containerRef","usePositioning","targetRef","popperOptions"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,yBAAyB;;;;;+BAMTA;;;eAAAA;;;kCAJ4C;AAIrD,SAASA,uBAAuBC,KAAwB;UAM7D,EAEAC,WAAA,KACAD;qBACY;UACVE,gBAAO;kBACPC;;gBAAwBC;uBAAY;sBACpCC;;2BAEGC,EAAAA;QACLC,iBAAA;QAEA,GAAAD,IAAAA,6CAAmBE,EAAYP,YAAKQ;;UAE5BD,WAAcE,cAAU,EAClC,GAAAD,IAAAA,gCAAA,EAAAE"}
1
+ {"version":3,"sources":["useComboboxPositioning.ts"],"sourcesContent":["// Brought from Fluent UI\n\nimport { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport type * as React from 'react';\nimport type { ComboboxBaseProps } from '@fluentui/react-combobox';\nimport type { UsePromptListboxFunctionalityParams } from './PromptListboxFunctionality.types';\nimport type { PositioningShorthandValue } from '@fluentui/react-positioning';\n\nexport function useComboboxPositioning(\n props: ComboboxBaseProps & Required<Pick<UsePromptListboxFunctionalityParams, 'fluid'>>,\n): [\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n listboxRef: React.MutableRefObject<any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n triggerRef: React.MutableRefObject<any>,\n] {\n const { positioning, fluid } = props;\n\n const fallbackPositions: PositioningShorthandValue[] = ['below'];\n\n // popper options\n const popperOptions = {\n position: 'below' as const,\n align: 'start' as const,\n offset: { crossAxis: 0, mainAxis: 2 },\n fallbackPositions: fallbackPositions,\n matchTargetSize: fluid ? ('width' as const) : undefined,\n ...resolvePositioningShorthand(positioning),\n };\n\n const { targetRef, containerRef } = usePositioning(popperOptions);\n\n return [containerRef, targetRef];\n}\n"],"names":["useComboboxPositioning","props","positioning","fallbackPositions","popperOptions","position","align","offset","crossAxis","mainAxis","matchTargetSize","resolvePositioningShorthand","containerRef","targetRef","usePositioning"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,yBAAyB;;;;;+BAQTA;;;eAAAA;;;kCAN4C;AAMrD,SAASA,uBACdC,KAAuF;UAOvF,EAEAC,WAAMC,OAAkD,KAAQF;UAEhEE,oBAAiB;QAAA;KAAA;qBACXC;UACJC,gBAAU;kBACVC;eACAC;gBAAUC;uBAAcC;sBAAY;;2BAEpCC;yBACGC,QAAAA,UAA4BT;QACjC,GAAAS,IAAAA,6CAAA,EAAAT,YAAA;;UAIA,WAAQU,cAAcC,KAAUC,IAAAA,gCAAA,EAAAV;IAClC,OAAA;QAAAQ;QAAAC;KAAA"}
@@ -22,7 +22,7 @@ const _useTriggerKeyDown = require("./useTriggerKeyDown");
22
22
  const _PromptListbox = require("../PromptListbox");
23
23
  const _PromptOption = require("../PromptOption");
24
24
  function usePromptListboxFunctionality(params) {
25
- const { positioning, onOpenChange, onSelectionModeChange, listboxProps } = params;
25
+ const { positioning, onOpenChange, onSelectionModeChange, listboxProps, fluid = false } = params;
26
26
  const { listboxRef: activeDescendantListboxRef, activeParentRef, controller: activeDescendantController } = (0, _reactaria.useActiveDescendant)({
27
27
  matchOption: (el)=>el.classList.contains(_PromptOption.promptOptionClassNames.root)
28
28
  });
@@ -115,7 +115,8 @@ function usePromptListboxFunctionality(params) {
115
115
  hideActiveDescendant
116
116
  ]);
117
117
  const [comboboxPopupRef, comboboxTargetRef] = (0, _useComboboxPositioning.useComboboxPositioning)({
118
- positioning
118
+ positioning,
119
+ fluid
119
120
  });
120
121
  const listboxMergedRef = (0, _reactutilities.useMergedRefs)(comboboxPopupRef, activeDescendantListboxRef, listboxProps === null || listboxProps === void 0 ? void 0 : listboxProps.ref);
121
122
  const listbox = _react.useMemo(()=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["usePromptListboxFunctionality.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useActiveDescendant } from '@fluentui/react-aria';\nimport { mergeCallbacks, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport { TextCursorPositionPlugin } from '../../plugins/TextCursorPositionPlugin';\nimport { useOptionCollection } from './useOptionCollection';\nimport { useSelection } from './useSelection';\nimport { ArrowDown, ArrowLeft, ArrowRight, ArrowUp } from '@fluentui/keyboard-keys';\nimport { useComboboxPositioning } from './useComboboxPositioning';\nimport { useTriggerKeydown } from './useTriggerKeyDown';\nimport { PromptListbox } from '../PromptListbox';\nimport { promptOptionClassNames } from '../PromptOption';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\nimport type {\n UsePromptListboxFunctionalityParams,\n UsePromptListboxFunctionality,\n} from './PromptListboxFunctionality.types';\n\nexport function usePromptListboxFunctionality(\n params: UsePromptListboxFunctionalityParams,\n): UsePromptListboxFunctionality {\n const { positioning, onOpenChange, onSelectionModeChange, listboxProps } = params;\n const {\n listboxRef: activeDescendantListboxRef,\n activeParentRef,\n controller: activeDescendantController,\n } = useActiveDescendant<HTMLSpanElement, HTMLDivElement>({\n matchOption: el => el.classList.contains(promptOptionClassNames.root),\n });\n // useMergedRefs to normalize the ref into a React.RefObject type\n const triggerRef = useMergedRefs(activeParentRef);\n const selectionState = useSelection(listboxProps ?? {});\n const { selectOption } = selectionState;\n const optionCollection = useOptionCollection();\n const { getOptionById } = optionCollection;\n const [isInLastPosition, setIsInLastPosition] = React.useState(true);\n const [isInSelectionMode, setIsInSelectionMode] = React.useState(false);\n const [open, setOpen] = useControllableState({\n state: params.open,\n defaultState: params.defaultOpen,\n initialState: false,\n });\n\n const onBlur = (event: React.FocusEvent<HTMLSpanElement>) => {\n setOpen(false);\n onOpenChange?.(event, { event, type: 'focus', open: false });\n };\n\n const onFocus = (event: React.FocusEvent<HTMLSpanElement>) => {\n if (event.target === event.currentTarget) {\n setOpen(true);\n onOpenChange?.(event, { event, type: 'focus', open: true });\n }\n };\n\n const cursorPositionPlugin = <TextCursorPositionPlugin setIsInLastPosition={setIsInLastPosition} />;\n\n const onListboxBlur = React.useCallback(() => {\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n }, [onSelectionModeChange]);\n\n // handle combobox keyboard interaction\n const onKeyDown = useTriggerKeydown({\n ...optionCollection,\n activeDescendantController,\n getOptionById,\n onBlur: onListboxBlur,\n selectOption,\n isInLastPosition,\n open,\n multiselect: false,\n });\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n /**\n * Freeform combobox should not select\n */\n const onInputTriggerKeyDown: EditorInputProps['onKeyDown'] = useEventCallback(event => {\n // update typing state to true if the user is typing\n const action = getDropdownActionFromKey(event, { open, multiselect: false, isInLastPosition });\n if (\n event.key === ArrowLeft ||\n event.key === ArrowRight ||\n (!isInLastPosition && (event.key === ArrowDown || event.key === ArrowUp)) ||\n (action === 'Type' && isInLastPosition) ||\n action === 'Type'\n ) {\n activeDescendantController.blur();\n setHideActiveDescendant(true);\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n } else if (\n action === 'Next' ||\n action === 'Previous' ||\n action === 'First' ||\n action === 'Last' ||\n action === 'PageUp' ||\n action === 'PageDown'\n ) {\n setHideActiveDescendant(false);\n setIsInSelectionMode(true);\n onSelectionModeChange?.(true);\n }\n });\n\n React.useEffect(() => {\n if (hideActiveDescendant) {\n triggerRef.current?.removeAttribute('aria-activedescendant');\n }\n // We only want to run this when the hideActiveDescendant changes, if the triggerRef\n // is undefined, there's no need to remove theAttribute and we shouldn't be adding\n // refs as dependencies since it can blow up the number of runs.\n // eslint-disable-next-line react-compiler/react-compiler\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hideActiveDescendant]);\n\n const [comboboxPopupRef, comboboxTargetRef] = useComboboxPositioning({ positioning });\n\n const listboxMergedRef = useMergedRefs(comboboxPopupRef, activeDescendantListboxRef, listboxProps?.ref);\n const listbox = React.useMemo(() => {\n return (\n <PromptListbox\n open={open}\n {...listboxProps}\n {...optionCollection}\n {...selectionState}\n ref={listboxMergedRef}\n activeDescendantController={activeDescendantController}\n />\n );\n }, [activeDescendantController, listboxMergedRef, listboxProps, open, optionCollection, selectionState]);\n\n return {\n promptListbox: listbox,\n triggerProps: {\n ref: triggerRef,\n onBlur,\n onFocus,\n onKeyDown: useEventCallback(mergeCallbacks(onKeyDown, onInputTriggerKeyDown)),\n isInSelectionMode,\n },\n containerRef: comboboxTargetRef,\n cursorPositionPlugin,\n };\n}\n"],"names":["usePromptListboxFunctionality","params","positioning","listboxRef","matchOption","onSelectionModeChange","listboxProps","selectOption","selectionState","activeParentRef","optionCollection","controller","getOptionById","useActiveDescendant","isInLastPosition","isInSelectionMode","setIsInSelectionMode","useState","root","defaultState","defaultOpen","initialState","useSelection","onBlur","onOpenChange","type","setIsInLastPosition","React","open","onFocus","event","target","setOpen","cursorPositionPlugin","onListboxBlur","currentTarget","onKeyDown","useTriggerKeydown","activeDescendantController","onInputTriggerKeyDown","useEventCallback","action","hideActiveDescendant","key","ArrowRight","ArrowDown","ArrowUp","triggerRef","setHideActiveDescendant","useEffect","comboboxTargetRef","_triggerRef_current","current","removeAttribute","PromptListbox","listboxMergedRef","useMergedRefs","comboboxPopupRef","activeDescendantListboxRef","ref","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["usePromptListboxFunctionality.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useActiveDescendant } from '@fluentui/react-aria';\nimport { mergeCallbacks, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport { TextCursorPositionPlugin } from '../../plugins/TextCursorPositionPlugin';\nimport { useOptionCollection } from './useOptionCollection';\nimport { useSelection } from './useSelection';\nimport { ArrowDown, ArrowLeft, ArrowRight, ArrowUp } from '@fluentui/keyboard-keys';\nimport { useComboboxPositioning } from './useComboboxPositioning';\nimport { useTriggerKeydown } from './useTriggerKeyDown';\nimport { PromptListbox } from '../PromptListbox';\nimport { promptOptionClassNames } from '../PromptOption';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\nimport type {\n UsePromptListboxFunctionalityParams,\n UsePromptListboxFunctionality,\n} from './PromptListboxFunctionality.types';\n\nexport function usePromptListboxFunctionality(\n params: UsePromptListboxFunctionalityParams,\n): UsePromptListboxFunctionality {\n const { positioning, onOpenChange, onSelectionModeChange, listboxProps, fluid = false } = params;\n const {\n listboxRef: activeDescendantListboxRef,\n activeParentRef,\n controller: activeDescendantController,\n } = useActiveDescendant<HTMLSpanElement, HTMLDivElement>({\n matchOption: el => el.classList.contains(promptOptionClassNames.root),\n });\n // useMergedRefs to normalize the ref into a React.RefObject type\n const triggerRef = useMergedRefs(activeParentRef);\n const selectionState = useSelection(listboxProps ?? {});\n const { selectOption } = selectionState;\n const optionCollection = useOptionCollection();\n const { getOptionById } = optionCollection;\n const [isInLastPosition, setIsInLastPosition] = React.useState(true);\n const [isInSelectionMode, setIsInSelectionMode] = React.useState(false);\n const [open, setOpen] = useControllableState({\n state: params.open,\n defaultState: params.defaultOpen,\n initialState: false,\n });\n\n const onBlur = (event: React.FocusEvent<HTMLSpanElement>) => {\n setOpen(false);\n onOpenChange?.(event, { event, type: 'focus', open: false });\n };\n\n const onFocus = (event: React.FocusEvent<HTMLSpanElement>) => {\n if (event.target === event.currentTarget) {\n setOpen(true);\n onOpenChange?.(event, { event, type: 'focus', open: true });\n }\n };\n\n const cursorPositionPlugin = <TextCursorPositionPlugin setIsInLastPosition={setIsInLastPosition} />;\n\n const onListboxBlur = React.useCallback(() => {\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n }, [onSelectionModeChange]);\n\n // handle combobox keyboard interaction\n const onKeyDown = useTriggerKeydown({\n ...optionCollection,\n activeDescendantController,\n getOptionById,\n onBlur: onListboxBlur,\n selectOption,\n isInLastPosition,\n open,\n multiselect: false,\n });\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n /**\n * Freeform combobox should not select\n */\n const onInputTriggerKeyDown: EditorInputProps['onKeyDown'] = useEventCallback(event => {\n // update typing state to true if the user is typing\n const action = getDropdownActionFromKey(event, { open, multiselect: false, isInLastPosition });\n if (\n event.key === ArrowLeft ||\n event.key === ArrowRight ||\n (!isInLastPosition && (event.key === ArrowDown || event.key === ArrowUp)) ||\n (action === 'Type' && isInLastPosition) ||\n action === 'Type'\n ) {\n activeDescendantController.blur();\n setHideActiveDescendant(true);\n setIsInSelectionMode(false);\n onSelectionModeChange?.(false);\n } else if (\n action === 'Next' ||\n action === 'Previous' ||\n action === 'First' ||\n action === 'Last' ||\n action === 'PageUp' ||\n action === 'PageDown'\n ) {\n setHideActiveDescendant(false);\n setIsInSelectionMode(true);\n onSelectionModeChange?.(true);\n }\n });\n\n React.useEffect(() => {\n if (hideActiveDescendant) {\n triggerRef.current?.removeAttribute('aria-activedescendant');\n }\n // We only want to run this when the hideActiveDescendant changes, if the triggerRef\n // is undefined, there's no need to remove theAttribute and we shouldn't be adding\n // refs as dependencies since it can blow up the number of runs.\n // eslint-disable-next-line react-compiler/react-compiler\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hideActiveDescendant]);\n\n const [comboboxPopupRef, comboboxTargetRef] = useComboboxPositioning({ positioning, fluid });\n\n const listboxMergedRef = useMergedRefs(comboboxPopupRef, activeDescendantListboxRef, listboxProps?.ref);\n const listbox = React.useMemo(() => {\n return (\n <PromptListbox\n open={open}\n {...listboxProps}\n {...optionCollection}\n {...selectionState}\n ref={listboxMergedRef}\n activeDescendantController={activeDescendantController}\n />\n );\n }, [activeDescendantController, listboxMergedRef, listboxProps, open, optionCollection, selectionState]);\n\n return {\n promptListbox: listbox,\n triggerProps: {\n ref: triggerRef,\n onBlur,\n onFocus,\n onKeyDown: useEventCallback(mergeCallbacks(onKeyDown, onInputTriggerKeyDown)),\n isInSelectionMode,\n },\n containerRef: comboboxTargetRef,\n cursorPositionPlugin,\n };\n}\n"],"names":["usePromptListboxFunctionality","params","positioning","listboxRef","matchOption","onSelectionModeChange","listboxProps","fluid","triggerRef","optionCollection","useOptionCollection","activeParentRef","getOptionById","controller","isInLastPosition","setIsInLastPosition","useActiveDescendant","isInSelectionMode","setOpen","classList","useControllableState","root","initialState","selectionState","useSelection","event","open","React","useState","target","currentTarget","onOpenChange","type","cursorPositionPlugin","setIsInSelectionMode","onKeyDown","onBlur","onListboxBlur","selectOption","useTriggerKeydown","hideActiveDescendant","activeDescendantController","onInputTriggerKeyDown","multiselect","ArrowDown","setHideActiveDescendant","action","useEffect","comboboxPopupRef","_triggerRef_current","current","removeAttribute","PromptListbox","listboxMergedRef","ref","listbox","onFocus"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-copilot/react-prompt-listbox",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "PromptListbox for input components using EditorInput.",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -12,13 +12,13 @@
12
12
  },
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
- "@fluentui-copilot/chat-input-plugins": "^0.1.1",
16
- "@fluentui-copilot/react-chat-input-plugins": "^0.1.1",
17
- "@fluentui-copilot/react-editor-input": "^0.1.1",
18
- "@fluentui-copilot/react-prompt-input": "^0.1.1",
15
+ "@fluentui-copilot/chat-input-plugins": "^0.1.3",
16
+ "@fluentui-copilot/react-chat-input-plugins": "^0.1.3",
17
+ "@fluentui-copilot/react-editor-input": "^0.1.3",
18
+ "@fluentui-copilot/react-prompt-input": "^0.1.3",
19
19
  "@fluentui-copilot/react-provider": "^0.8.4",
20
- "@fluentui-copilot/react-text-editor": "^0.1.7",
21
- "@fluentui-copilot/text-editor": "^0.0.5",
20
+ "@fluentui-copilot/react-text-editor": "^0.1.8",
21
+ "@fluentui-copilot/text-editor": "^0.0.6",
22
22
  "@swc/helpers": "^0.5.1"
23
23
  },
24
24
  "peerDependencies": {