@fluentui-copilot/react-prompt-listbox 0.0.0-nightly-20251002-0405-17b34fb7.1 → 0.0.0-nightly-20251010-0406-7df7c6d1.1

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,9 +2,9 @@
2
2
  "name": "@fluentui-copilot/react-prompt-listbox",
3
3
  "entries": [
4
4
  {
5
- "date": "Thu, 02 Oct 2025 04:13:20 GMT",
6
- "tag": "@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20251002-0405-17b34fb7.1",
7
- "version": "0.0.0-nightly-20251002-0405-17b34fb7.1",
5
+ "date": "Fri, 10 Oct 2025 04:08:18 GMT",
6
+ "tag": "@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20251010-0406-7df7c6d1.1",
7
+ "version": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
8
8
  "comments": {
9
9
  "prerelease": [
10
10
  {
package/CHANGELOG.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Change Log - @fluentui-copilot/react-prompt-listbox
2
2
 
3
- This log was last generated on Thu, 02 Oct 2025 04:13:20 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 10 Oct 2025 04:08:18 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## [0.0.0-nightly-20251002-0405-17b34fb7.1](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20251002-0405-17b34fb7.1)
7
+ ## [0.0.0-nightly-20251010-0406-7df7c6d1.1](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20251010-0406-7df7c6d1.1)
8
8
 
9
- Thu, 02 Oct 2025 04:13:20 GMT
10
- [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/react-prompt-listbox_v0.10.3..@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20251002-0405-17b34fb7.1)
9
+ Fri, 10 Oct 2025 04:08:18 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/react-prompt-listbox_v0.10.3..@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20251010-0406-7df7c6d1.1)
11
11
 
12
12
  ### Changes
13
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-copilot/react-prompt-listbox",
3
- "version": "0.0.0-nightly-20251002-0405-17b34fb7.1",
3
+ "version": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
4
4
  "description": "PromptListbox for input components using EditorInput.",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -12,15 +12,15 @@
12
12
  },
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
- "@fluentui-copilot/chat-input-plugins": "0.0.0-nightly-20251002-0405-17b34fb7.1",
16
- "@fluentui-copilot/react-chat-input-plugins": "0.0.0-nightly-20251002-0405-17b34fb7.1",
17
- "@fluentui-copilot/react-editor-input": "0.0.0-nightly-20251002-0405-17b34fb7.1",
18
- "@fluentui-copilot/react-input-listbox": "0.0.0-nightly-20251002-0405-17b34fb7.1",
19
- "@fluentui-copilot/react-prompt-input": "0.0.0-nightly-20251002-0405-17b34fb7.1",
20
- "@fluentui-copilot/react-provider": "0.0.0-nightly-20251002-0405-17b34fb7.1",
21
- "@fluentui-copilot/react-text-editor": "0.0.0-nightly-20251002-0405-17b34fb7.1",
22
- "@fluentui-copilot/text-editor": "0.0.0-nightly-20251002-0405-17b34fb7.1",
23
- "@fluentui-copilot/tokens": "0.0.0-nightly-20251002-0405-17b34fb7.1",
15
+ "@fluentui-copilot/chat-input-plugins": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
16
+ "@fluentui-copilot/react-chat-input-plugins": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
17
+ "@fluentui-copilot/react-editor-input": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
18
+ "@fluentui-copilot/react-input-listbox": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
19
+ "@fluentui-copilot/react-prompt-input": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
20
+ "@fluentui-copilot/react-provider": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
21
+ "@fluentui-copilot/react-text-editor": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
22
+ "@fluentui-copilot/text-editor": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
23
+ "@fluentui-copilot/tokens": "0.0.0-nightly-20251010-0406-7df7c6d1.1",
24
24
  "@swc/helpers": "^0.5.1"
25
25
  },
26
26
  "peerDependencies": {
@@ -35,10 +35,10 @@
35
35
  "@fluentui/react-shared-contexts": ">=9.25.1 <10.0.0",
36
36
  "@fluentui/react-tabster": ">=9.26.5 <10.0.0",
37
37
  "@fluentui/react-utilities": ">=9.24.1 <10.0.0",
38
- "@types/react": ">=16.14.0 <19.0.0",
39
- "@types/react-dom": ">=16.9.8 <19.0.0",
40
- "react": ">=16.14.0 <19.0.0",
41
- "react-dom": ">=16.14.0 <19.0.0"
38
+ "@types/react": ">=16.14.0 <20.0.0",
39
+ "@types/react-dom": ">=16.9.8 <20.0.0",
40
+ "react": ">=16.14.0 <20.0.0",
41
+ "react-dom": ">=16.14.0 <20.0.0"
42
42
  },
43
43
  "beachball": {},
44
44
  "exports": {
package/dist/index.d.ts DELETED
@@ -1,132 +0,0 @@
1
- import { ActiveOptionChangeData } from '@fluentui-copilot/react-input-listbox';
2
- import type { EditorInputProps } from '@fluentui-copilot/react-editor-input';
3
- import type { EventData } from '@fluentui/react-utilities';
4
- import type { EventHandler } from '@fluentui/react-utilities';
5
- import type { InputListboxProps } from '@fluentui-copilot/react-input-listbox';
6
- import type { JSXElement } from '@fluentui/react-components';
7
- import { Option as Option_2 } from '@fluentui-copilot/react-input-listbox';
8
- import { optionClassNames } from '@fluentui-copilot/react-input-listbox';
9
- import { OptionOnSelectData } from '@fluentui-copilot/react-input-listbox';
10
- import { OptionProps } from '@fluentui-copilot/react-input-listbox';
11
- import { OptionSlots } from '@fluentui-copilot/react-input-listbox';
12
- import { OptionState } from '@fluentui-copilot/react-input-listbox';
13
- import { OptionValue } from '@fluentui-copilot/react-input-listbox';
14
- import { OverrideActionHandler } from '@fluentui-copilot/react-input-listbox';
15
- import { OverrideActionHandlerOptions } from '@fluentui-copilot/react-input-listbox';
16
- import { OverrideActionHandlerResult } from '@fluentui-copilot/react-input-listbox';
17
- import type { PortalProps } from '@fluentui/react-components';
18
- import type { PositioningShorthand } from '@fluentui/react-positioning';
19
- import * as React_2 from 'react';
20
- import { renderOption_unstable } from '@fluentui-copilot/react-input-listbox';
21
- import type { UseInputListboxFunctionalityParams } from '@fluentui-copilot/react-input-listbox';
22
- import { useInputListboxOptionStyles_unstable } from '@fluentui-copilot/react-input-listbox';
23
- import { useOption_unstable } from '@fluentui-copilot/react-input-listbox';
24
-
25
- export { ActiveOptionChangeData }
26
-
27
- export declare type OnOpenChangeData = (EventData<'click', React_2.MouseEvent<HTMLSpanElement>> | EventData<'focus', React_2.FocusEvent<HTMLSpanElement>> | EventData<'keyboard', React_2.KeyboardEvent<HTMLSpanElement>>) & {
28
- open: boolean;
29
- };
30
-
31
- export { Option_2 as Option }
32
-
33
- export { optionClassNames }
34
-
35
- export { OptionOnSelectData }
36
-
37
- export { OptionProps }
38
-
39
- export { OptionSlots }
40
-
41
- export { OptionState }
42
-
43
- export { OptionValue }
44
-
45
- export { OverrideActionHandler }
46
-
47
- export { OverrideActionHandlerOptions }
48
-
49
- export { OverrideActionHandlerResult }
50
-
51
- export { renderOption_unstable }
52
-
53
- export { useInputListboxOptionStyles_unstable }
54
-
55
- export { useOption_unstable }
56
-
57
- export declare type UsePromptListboxFunctionality<ContainerElementType extends HTMLElement> = {
58
- /**
59
- * Component to be rendered in the Input component. This should be passed to the listbox prop.
60
- */
61
- promptListbox: JSXElement;
62
- /**
63
- * Props to be spread in the PromptInput, these props are needed for the keyboard behavior to
64
- * work correctly.
65
- */
66
- triggerProps: {
67
- ref: React_2.MutableRefObject<HTMLSpanElement | null>;
68
- /**
69
- * Whether the listbox is being used to go through options or the user is currently typing.
70
- */
71
- isInSelectionMode: boolean;
72
- } & Required<Pick<EditorInputProps, 'onBlur' | 'onFocus' | 'onKeyDown'>>;
73
- /**
74
- * Ref used to point which element the listbox should be anchored to. Most use cases
75
- * will provide this prop to the PromptInput's EditorInput (since this is the root slot,
76
- * this is provided directly to the component and not the slot).
77
- *
78
- * Note: If the containerRef is the same as the trigger, the ref provided in triggerProps needs
79
- * to be merged with this one using `useMergedRefs(containerRef, triggerProps.ref);`
80
- */
81
- containerRef: React_2.MutableRefObject<ContainerElementType | null>;
82
- /**
83
- * Plugin used to tell where the cursor is in the EditorInput, this is important for the
84
- * keyboard behavior. This should be passed as children in the PromptInput.
85
- */
86
- cursorPositionPlugin: JSXElement;
87
- };
88
-
89
- export declare function usePromptListboxFunctionality<TriggerElementType extends HTMLElement = HTMLSpanElement, ContainerElementType extends HTMLElement = HTMLDivElement>(params: UsePromptListboxFunctionalityParams): UsePromptListboxFunctionality<ContainerElementType>;
90
-
91
- export declare type UsePromptListboxFunctionalityParams = UseInputListboxFunctionalityParams & {
92
- open?: boolean;
93
- defaultOpen?: boolean;
94
- onOpenChange?: EventHandler<OnOpenChangeData>;
95
- positioning?: PositioningShorthand;
96
- /**
97
- * Whether the listbox's width should take all the available space or only
98
- * the required space.
99
- *
100
- * @default false
101
- */
102
- fluid?: boolean;
103
- /**
104
- * Props to be passed to the InputListbox component
105
- */
106
- listboxProps?: Partial<InputListboxProps> & {
107
- ref?: React_2.RefObject<HTMLDivElement | null>;
108
- };
109
- /**
110
- * Whether to allow reaching the listbox options by arrowing up at the start of the input.
111
- * Note, this prop is meant to be used with the following positioning props:
112
- * ```ts
113
- * usePromptListboxFunctionality({
114
- * positioning: {
115
- * position: 'above',
116
- * fallbackPositions: ['above']
117
- * }
118
- * });
119
- * ```
120
- * This is useful when using PromptListbox with other components such as ChatInput since
121
- * the input will always stay at the bottom therefore the listbox would always get cut.
122
- *
123
- * @default false
124
- */
125
- allowArrowUpNavigation?: boolean;
126
- /**
127
- * Whether to render the listbox inline or use a portal.
128
- */
129
- inline?: boolean;
130
- } & Pick<PortalProps, 'mountNode'>;
131
-
132
- export { }
@@ -1,55 +0,0 @@
1
- import { createPresenceComponent, motionTokens } from '@fluentui/react-components';
2
- const collapseMotion = ({ element })=>{
3
- const fromOpacity = 0;
4
- const toOpacity = 1;
5
- const fromHeight = '0';
6
- const toHeight = `${element.scrollHeight}px`;
7
- const overflow = 'hidden';
8
- const duration = motionTokens.durationNormal;
9
- const easing = motionTokens.curveEasyEaseMax;
10
- const enterKeyframes = [
11
- {
12
- opacity: fromOpacity,
13
- maxHeight: fromHeight,
14
- overflow
15
- },
16
- // Transition to the height of the content, at 99.99% of the duration.
17
- {
18
- opacity: toOpacity,
19
- maxHeight: toHeight,
20
- offset: 0.9999,
21
- overflow
22
- },
23
- // On completion, remove the maxHeight because the content might need to expand later.
24
- {
25
- opacity: toOpacity,
26
- maxHeight: 'unset',
27
- overflow
28
- }
29
- ];
30
- const exitKeyframes = [
31
- {
32
- opacity: toOpacity,
33
- maxHeight: toHeight,
34
- overflow
35
- },
36
- {
37
- opacity: fromOpacity,
38
- maxHeight: fromHeight,
39
- overflow
40
- }
41
- ];
42
- return {
43
- enter: {
44
- duration,
45
- easing,
46
- keyframes: enterKeyframes
47
- },
48
- exit: {
49
- duration,
50
- easing,
51
- keyframes: exitKeyframes
52
- }
53
- };
54
- };
55
- export const PromptListboxMotion = createPresenceComponent(collapseMotion);
@@ -1 +0,0 @@
1
- {"version":3,"sources":["PromptListboxMotion.ts"],"sourcesContent":["import { createPresenceComponent, motionTokens } from '@fluentui/react-components';\nimport type { PresenceMotionFn } from '@fluentui/react-components';\n\nconst collapseMotion: PresenceMotionFn = ({ element }) => {\n const fromOpacity = 0;\n const toOpacity = 1;\n const fromHeight = '0';\n const toHeight = `${element.scrollHeight}px`;\n const overflow = 'hidden';\n\n const duration = motionTokens.durationNormal;\n const easing = motionTokens.curveEasyEaseMax;\n\n const enterKeyframes = [\n { opacity: fromOpacity, maxHeight: fromHeight, overflow },\n // Transition to the height of the content, at 99.99% of the duration.\n { opacity: toOpacity, maxHeight: toHeight, offset: 0.9999, overflow },\n // On completion, remove the maxHeight because the content might need to expand later.\n { opacity: toOpacity, maxHeight: 'unset', overflow },\n ];\n\n const exitKeyframes = [\n { opacity: toOpacity, maxHeight: toHeight, overflow },\n { opacity: fromOpacity, maxHeight: fromHeight, overflow },\n ];\n\n return {\n enter: { duration, easing, keyframes: enterKeyframes },\n exit: { duration, easing, keyframes: exitKeyframes },\n };\n};\n\nexport const PromptListboxMotion: ReturnType<typeof createPresenceComponent<{}>> =\n createPresenceComponent(collapseMotion);\n"],"names":["createPresenceComponent","motionTokens","collapseMotion","element","fromOpacity","toOpacity","fromHeight","toHeight","scrollHeight","overflow","duration","durationNormal","easing","curveEasyEaseMax","enterKeyframes","opacity","maxHeight","offset","exitKeyframes","enter","keyframes","exit","PromptListboxMotion"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,uBAAuB,EAAEC,YAAY,QAAQ,6BAA6B;AAGnF,MAAMC,iBAAmC,CAAC,EAAEC,OAAO,EAAE;IACnD,MAAMC,cAAc;IACpB,MAAMC,YAAY;IAClB,MAAMC,aAAa;IACnB,MAAMC,WAAW,CAAC,EAAEJ,QAAQK,YAAY,CAAC,EAAE,CAAC;IAC5C,MAAMC,WAAW;IAEjB,MAAMC,WAAWT,aAAaU,cAAc;IAC5C,MAAMC,SAASX,aAAaY,gBAAgB;IAE5C,MAAMC,iBAAiB;QACrB;YAAEC,SAASX;YAAaY,WAAWV;YAAYG;QAAS;QACxD,sEAAsE;QACtE;YAAEM,SAASV;YAAWW,WAAWT;YAAUU,QAAQ;YAAQR;QAAS;QACpE,sFAAsF;QACtF;YAAEM,SAASV;YAAWW,WAAW;YAASP;QAAS;KACpD;IAED,MAAMS,gBAAgB;QACpB;YAAEH,SAASV;YAAWW,WAAWT;YAAUE;QAAS;QACpD;YAAEM,SAASX;YAAaY,WAAWV;YAAYG;QAAS;KACzD;IAED,OAAO;QACLU,OAAO;YAAET;YAAUE;YAAQQ,WAAWN;QAAe;QACrDO,MAAM;YAAEX;YAAUE;YAAQQ,WAAWF;QAAc;IACrD;AACF;AAEA,OAAO,MAAMI,sBACXtB,wBAAwBE,gBAAgB"}
@@ -1,26 +0,0 @@
1
- // Brought from Fluent UI
2
- import { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';
3
- export function useListboxPositioning(props) {
4
- const { positioning, fluid } = props;
5
- const fallbackPositions = [
6
- 'below'
7
- ];
8
- // popper options
9
- const popperOptions = {
10
- position: 'below',
11
- align: 'start',
12
- offset: {
13
- crossAxis: 0,
14
- mainAxis: 2
15
- },
16
- fallbackPositions: fallbackPositions,
17
- matchTargetSize: fluid ? 'width' : undefined,
18
- autoSize: true,
19
- ...resolvePositioningShorthand(positioning)
20
- };
21
- const { containerRef: listboxRef, targetRef: anchorRef } = usePositioning(popperOptions);
22
- return [
23
- listboxRef,
24
- anchorRef
25
- ];
26
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["useListboxPositioning.ts"],"sourcesContent":["// Brought from Fluent UI\n\nimport { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport type * as React from 'react';\nimport type { UsePromptListboxFunctionalityParams } from './usePromptListboxFunctionalityV2';\nimport type { PositioningShorthandValue } from '@fluentui/react-positioning';\n\nexport function useListboxPositioning<AnchorElementType extends HTMLElement = HTMLSpanElement>(\n props: Pick<UsePromptListboxFunctionalityParams, 'fluid' | 'positioning'>,\n): [listboxRef: React.RefObject<HTMLSpanElement | null>, anchorRef: React.RefObject<AnchorElementType | null>] {\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 autoSize: true,\n ...resolvePositioningShorthand(positioning),\n };\n\n const { containerRef: listboxRef, targetRef: anchorRef } = usePositioning(popperOptions);\n\n return [listboxRef, anchorRef];\n}\n"],"names":["resolvePositioningShorthand","usePositioning","useListboxPositioning","props","positioning","fluid","fallbackPositions","popperOptions","position","align","offset","crossAxis","mainAxis","matchTargetSize","undefined","autoSize","containerRef","listboxRef","targetRef","anchorRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,yBAAyB;AAEzB,SAASA,2BAA2B,EAAEC,cAAc,QAAQ,8BAA8B;AAK1F,OAAO,SAASC,sBACdC,KAAyE;IAEzE,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;QAC9CC,UAAU;QACV,GAAGf,4BAA4BI,YAAY;IAC7C;IAEA,MAAM,EAAEY,cAAcC,UAAU,EAAEC,WAAWC,SAAS,EAAE,GAAGlB,eAAeM;IAE1E,OAAO;QAACU;QAAYE;KAAU;AAChC"}
@@ -1,124 +0,0 @@
1
- import * as React from 'react';
2
- import { InputListbox, useInputListboxFunctionality } from '@fluentui-copilot/react-input-listbox';
3
- import { PromptListboxMotion } from '../motion/PromptListboxMotion';
4
- import { mergeCallbacks, useControllableState, useEventCallback, useId, useMergedRefs } from '@fluentui/react-utilities';
5
- import { CursorPositionPlugin } from '../../plugins/CursorPositionPlugin';
6
- import { useListboxPositioning } from './useListboxPositioning';
7
- import { Portal } from '@fluentui/react-components';
8
- export function usePromptListboxFunctionality(params) {
9
- var _params_listboxProps, _params_listboxProps1;
10
- const { fluid = false, allowArrowUpNavigation = false, onSelectionModeChange } = params;
11
- const [open, setOpen] = useControllableState({
12
- state: params.open,
13
- defaultState: params.defaultOpen,
14
- initialState: false
15
- });
16
- const [cursorPosition, setCursorPosition] = React.useState('end');
17
- const overrideActionHandler = (e, { activeOption, action, activeDescendantController, isInSelectionMode })=>{
18
- var _params_overrideActionHandler;
19
- const atStart = allowArrowUpNavigation && (cursorPosition === 'start' || cursorPosition === 'start-end');
20
- const atEnd = cursorPosition === 'end' || cursorPosition === 'start-end';
21
- let newAction = undefined;
22
- let newIsInSelection = undefined;
23
- const firstOption = activeDescendantController.first({
24
- passive: true
25
- });
26
- switch(action){
27
- case 'Next':
28
- if (!isInSelectionMode && !atEnd) {
29
- newAction = 'Type';
30
- newIsInSelection = false;
31
- }
32
- break;
33
- case 'Previous':
34
- if (!isInSelectionMode && !atStart) {
35
- newAction = 'Type';
36
- newIsInSelection = false;
37
- } else if (isInSelectionMode && !allowArrowUpNavigation && atEnd && activeOption !== undefined && activeOption.id === firstOption) {
38
- newAction = 'Type';
39
- newIsInSelection = false;
40
- e.preventDefault();
41
- }
42
- break;
43
- case 'First':
44
- case 'Last':
45
- case 'PageDown':
46
- case 'PageUp':
47
- if (!isInSelectionMode) {
48
- newAction = 'Type';
49
- newIsInSelection = false;
50
- }
51
- break;
52
- }
53
- const userOverrides = (_params_overrideActionHandler = params.overrideActionHandler) === null || _params_overrideActionHandler === void 0 ? void 0 : _params_overrideActionHandler.call(params, e, {
54
- activeOption,
55
- action,
56
- activeDescendantController,
57
- isInSelectionMode
58
- });
59
- return {
60
- action: newAction,
61
- isInSelectionMode: newIsInSelection,
62
- ...userOverrides
63
- };
64
- };
65
- const baseListboxFunctionality = useInputListboxFunctionality({
66
- ...params,
67
- onSelectionModeChange,
68
- overrideActionHandler
69
- });
70
- const { onBlur: baseOnBlur, onKeyDown: baseOnKeyDown, ref: triggerRef, isInSelectionMode } = baseListboxFunctionality.triggerProps;
71
- const onFocus = (event)=>{
72
- if (event.target === event.currentTarget) {
73
- var _params_onOpenChange;
74
- setOpen(true);
75
- (_params_onOpenChange = params.onOpenChange) === null || _params_onOpenChange === void 0 ? void 0 : _params_onOpenChange.call(params, event, {
76
- event,
77
- type: 'focus',
78
- open: true
79
- });
80
- }
81
- };
82
- const onBlur = useEventCallback(mergeCallbacks(baseOnBlur, (e)=>{
83
- var _params_onOpenChange;
84
- setOpen(false);
85
- (_params_onOpenChange = params.onOpenChange) === null || _params_onOpenChange === void 0 ? void 0 : _params_onOpenChange.call(params, e, {
86
- event: e,
87
- type: 'focus',
88
- open: false
89
- });
90
- }));
91
- const [listboxRef, anchorRef] = useListboxPositioning({
92
- fluid,
93
- positioning: params.positioning
94
- });
95
- const listboxId = useId('prompt-listbox', (_params_listboxProps = params.listboxProps) === null || _params_listboxProps === void 0 ? void 0 : _params_listboxProps.id);
96
- const cursorPositionPlugin = /*#__PURE__*/ React.createElement(CursorPositionPlugin, {
97
- setCursorPosition: setCursorPosition
98
- });
99
- const innerListbox = /*#__PURE__*/ React.createElement(InputListbox, {
100
- ...params.listboxProps,
101
- ...baseListboxFunctionality.inputListboxProps,
102
- id: listboxId,
103
- ref: useMergedRefs(baseListboxFunctionality.inputListboxProps.ref, listboxRef, (_params_listboxProps1 = params.listboxProps) === null || _params_listboxProps1 === void 0 ? void 0 : _params_listboxProps1.ref)
104
- });
105
- const listbox = /*#__PURE__*/ React.createElement(PromptListboxMotion, {
106
- visible: open
107
- }, /*#__PURE__*/ React.createElement("span", {
108
- "aria-owns": open ? listboxId : undefined
109
- }, open && (params.inline ? innerListbox : /*#__PURE__*/ React.createElement(Portal, {
110
- mountNode: params.mountNode
111
- }, innerListbox))));
112
- return {
113
- promptListbox: listbox,
114
- cursorPositionPlugin,
115
- triggerProps: {
116
- ref: triggerRef,
117
- isInSelectionMode,
118
- onFocus,
119
- onKeyDown: baseOnKeyDown,
120
- onBlur
121
- },
122
- containerRef: anchorRef
123
- };
124
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["usePromptListboxFunctionalityV2.tsx"],"sourcesContent":["import * as React from 'react';\nimport { InputListbox, useInputListboxFunctionality } from '@fluentui-copilot/react-input-listbox';\nimport { PromptListboxMotion } from '../motion/PromptListboxMotion';\nimport {\n mergeCallbacks,\n useControllableState,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { CursorPositionPlugin } from '../../plugins/CursorPositionPlugin';\nimport { useListboxPositioning } from './useListboxPositioning';\nimport { Portal } from '@fluentui/react-components';\nimport type { JSXElement } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type {\n InputListboxAction,\n InputListboxProps,\n UseInputListboxFunctionalityParams,\n OverrideActionHandler,\n} from '@fluentui-copilot/react-input-listbox';\nimport type { PortalProps } from '@fluentui/react-components';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\nimport type { PositioningShorthand } from '@fluentui/react-positioning';\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\nexport type UsePromptListboxFunctionalityParams = UseInputListboxFunctionalityParams & {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n positioning?: PositioningShorthand;\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 /**\n * Props to be passed to the InputListbox component\n */\n listboxProps?: Partial<InputListboxProps> & {\n ref?: React.RefObject<HTMLDivElement | null>;\n };\n\n /**\n * Whether to allow reaching the listbox options by arrowing up at the start of the input.\n * Note, this prop is meant to be used with the following positioning props:\n * ```ts\n * usePromptListboxFunctionality({\n * positioning: {\n * position: 'above',\n * fallbackPositions: ['above']\n * }\n * });\n * ```\n * This is useful when using PromptListbox with other components such as ChatInput since\n * the input will always stay at the bottom therefore the listbox would always get cut.\n *\n * @default false\n */\n allowArrowUpNavigation?: boolean;\n\n /**\n * Whether to render the listbox inline or use a portal.\n */\n inline?: boolean;\n} & Pick<PortalProps, 'mountNode'>;\n\nexport type UsePromptListboxFunctionality<ContainerElementType extends HTMLElement> = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSXElement;\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.MutableRefObject<HTMLSpanElement | null>;\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 /**\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 containerRef: React.MutableRefObject<ContainerElementType | null>;\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: JSXElement;\n};\n\nexport function usePromptListboxFunctionality<\n TriggerElementType extends HTMLElement = HTMLSpanElement,\n ContainerElementType extends HTMLElement = HTMLDivElement,\n>(params: UsePromptListboxFunctionalityParams): UsePromptListboxFunctionality<ContainerElementType> {\n const { fluid = false, allowArrowUpNavigation = false, onSelectionModeChange } = params;\n const [open, setOpen] = useControllableState({\n state: params.open,\n defaultState: params.defaultOpen,\n initialState: false,\n });\n const [cursorPosition, setCursorPosition] = React.useState<CursorPosition>('end');\n\n const overrideActionHandler: OverrideActionHandler = (\n e,\n { activeOption, action, activeDescendantController, isInSelectionMode },\n ) => {\n const atStart = allowArrowUpNavigation && (cursorPosition === 'start' || cursorPosition === 'start-end');\n const atEnd = cursorPosition === 'end' || cursorPosition === 'start-end';\n let newAction: InputListboxAction | undefined = undefined;\n let newIsInSelection: boolean | undefined = undefined;\n const firstOption = activeDescendantController.first({ passive: true });\n\n switch (action) {\n case 'Next':\n if (!isInSelectionMode && !atEnd) {\n newAction = 'Type';\n newIsInSelection = false;\n }\n break;\n case 'Previous':\n if (!isInSelectionMode && !atStart) {\n newAction = 'Type';\n newIsInSelection = false;\n } else if (\n isInSelectionMode &&\n !allowArrowUpNavigation &&\n atEnd &&\n activeOption !== undefined &&\n activeOption.id === firstOption\n ) {\n newAction = 'Type';\n newIsInSelection = false;\n e.preventDefault();\n }\n break;\n case 'First':\n case 'Last':\n case 'PageDown':\n case 'PageUp':\n if (!isInSelectionMode) {\n newAction = 'Type';\n newIsInSelection = false;\n }\n break;\n }\n\n const userOverrides = params.overrideActionHandler?.(e, {\n activeOption,\n action,\n activeDescendantController,\n isInSelectionMode,\n });\n\n return { action: newAction, isInSelectionMode: newIsInSelection, ...userOverrides };\n };\n\n const baseListboxFunctionality = useInputListboxFunctionality<TriggerElementType>({\n ...params,\n onSelectionModeChange,\n overrideActionHandler,\n });\n const {\n onBlur: baseOnBlur,\n onKeyDown: baseOnKeyDown,\n ref: triggerRef,\n isInSelectionMode,\n } = baseListboxFunctionality.triggerProps;\n\n const onFocus = (event: React.FocusEvent<HTMLSpanElement>) => {\n if (event.target === event.currentTarget) {\n setOpen(true);\n params.onOpenChange?.(event, { event, type: 'focus', open: true });\n }\n };\n\n const onBlur = useEventCallback(\n mergeCallbacks(baseOnBlur, (e: React.FocusEvent<TriggerElementType>) => {\n setOpen(false);\n params.onOpenChange?.(e, { event: e, type: 'focus', open: false });\n }),\n );\n\n const [listboxRef, anchorRef] = useListboxPositioning<ContainerElementType>({\n fluid,\n positioning: params.positioning,\n });\n\n const listboxId = useId('prompt-listbox', params.listboxProps?.id);\n const cursorPositionPlugin = <CursorPositionPlugin setCursorPosition={setCursorPosition} />;\n const innerListbox = (\n <InputListbox\n {...params.listboxProps}\n {...baseListboxFunctionality.inputListboxProps}\n id={listboxId}\n ref={useMergedRefs(baseListboxFunctionality.inputListboxProps.ref, listboxRef, params.listboxProps?.ref)}\n />\n );\n const listbox = (\n <PromptListboxMotion visible={open}>\n <span aria-owns={open ? listboxId : undefined}>\n {open && (params.inline ? innerListbox : <Portal mountNode={params.mountNode}>{innerListbox}</Portal>)}\n </span>\n </PromptListboxMotion>\n );\n\n return {\n promptListbox: listbox,\n cursorPositionPlugin,\n triggerProps: {\n ref: triggerRef,\n isInSelectionMode,\n onFocus,\n onKeyDown: baseOnKeyDown,\n onBlur,\n },\n containerRef: anchorRef,\n };\n}\n"],"names":["React","InputListbox","useInputListboxFunctionality","PromptListboxMotion","mergeCallbacks","useControllableState","useEventCallback","useId","useMergedRefs","CursorPositionPlugin","useListboxPositioning","Portal","usePromptListboxFunctionality","params","fluid","allowArrowUpNavigation","onSelectionModeChange","open","setOpen","state","defaultState","defaultOpen","initialState","cursorPosition","setCursorPosition","useState","overrideActionHandler","e","activeOption","action","activeDescendantController","isInSelectionMode","atStart","atEnd","newAction","undefined","newIsInSelection","firstOption","first","passive","id","preventDefault","userOverrides","baseListboxFunctionality","onBlur","baseOnBlur","onKeyDown","baseOnKeyDown","ref","triggerRef","triggerProps","onFocus","event","target","currentTarget","onOpenChange","type","listboxRef","anchorRef","positioning","listboxId","listboxProps","cursorPositionPlugin","innerListbox","inputListboxProps","listbox","visible","span","aria-owns","inline","mountNode","promptListbox","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,YAAY,EAAEC,4BAA4B,QAAQ,wCAAwC;AACnG,SAASC,mBAAmB,QAAQ,gCAAgC;AACpE,SACEC,cAAc,EACdC,oBAAoB,EACpBC,gBAAgB,EAChBC,KAAK,EACLC,aAAa,QACR,4BAA4B;AACnC,SAASC,oBAAoB,QAAQ,qCAAqC;AAC1E,SAASC,qBAAqB,QAAQ,0BAA0B;AAChE,SAASC,MAAM,QAAQ,6BAA6B;AAoGpD,OAAO,SAASC,8BAGdC,MAA2C;QA8FDA,sBAOyCA;IApGnF,MAAM,EAAEC,QAAQ,KAAK,EAAEC,yBAAyB,KAAK,EAAEC,qBAAqB,EAAE,GAAGH;IACjF,MAAM,CAACI,MAAMC,QAAQ,GAAGb,qBAAqB;QAC3Cc,OAAON,OAAOI,IAAI;QAClBG,cAAcP,OAAOQ,WAAW;QAChCC,cAAc;IAChB;IACA,MAAM,CAACC,gBAAgBC,kBAAkB,GAAGxB,MAAMyB,QAAQ,CAAiB;IAE3E,MAAMC,wBAA+C,CACnDC,GACA,EAAEC,YAAY,EAAEC,MAAM,EAAEC,0BAA0B,EAAEC,iBAAiB,EAAE;YA0CjDlB;QAxCtB,MAAMmB,UAAUjB,0BAA2BQ,CAAAA,mBAAmB,WAAWA,mBAAmB,WAAU;QACtG,MAAMU,QAAQV,mBAAmB,SAASA,mBAAmB;QAC7D,IAAIW,YAA4CC;QAChD,IAAIC,mBAAwCD;QAC5C,MAAME,cAAcP,2BAA2BQ,KAAK,CAAC;YAAEC,SAAS;QAAK;QAErE,OAAQV;YACN,KAAK;gBACH,IAAI,CAACE,qBAAqB,CAACE,OAAO;oBAChCC,YAAY;oBACZE,mBAAmB;gBACrB;gBACA;YACF,KAAK;gBACH,IAAI,CAACL,qBAAqB,CAACC,SAAS;oBAClCE,YAAY;oBACZE,mBAAmB;gBACrB,OAAO,IACLL,qBACA,CAAChB,0BACDkB,SACAL,iBAAiBO,aACjBP,aAAaY,EAAE,KAAKH,aACpB;oBACAH,YAAY;oBACZE,mBAAmB;oBACnBT,EAAEc,cAAc;gBAClB;gBACA;YACF,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;gBACH,IAAI,CAACV,mBAAmB;oBACtBG,YAAY;oBACZE,mBAAmB;gBACrB;gBACA;QACJ;QAEA,MAAMM,iBAAgB7B,gCAAAA,OAAOa,qBAAqB,cAA5Bb,oDAAAA,mCAAAA,QAA+Bc,GAAG;YACtDC;YACAC;YACAC;YACAC;QACF;QAEA,OAAO;YAAEF,QAAQK;YAAWH,mBAAmBK;YAAkB,GAAGM,aAAa;QAAC;IACpF;IAEA,MAAMC,2BAA2BzC,6BAAiD;QAChF,GAAGW,MAAM;QACTG;QACAU;IACF;IACA,MAAM,EACJkB,QAAQC,UAAU,EAClBC,WAAWC,aAAa,EACxBC,KAAKC,UAAU,EACflB,iBAAiB,EAClB,GAAGY,yBAAyBO,YAAY;IAEzC,MAAMC,UAAU,CAACC;QACf,IAAIA,MAAMC,MAAM,KAAKD,MAAME,aAAa,EAAE;gBAExCzC;YADAK,QAAQ;aACRL,uBAAAA,OAAO0C,YAAY,cAAnB1C,2CAAAA,0BAAAA,QAAsBuC,OAAO;gBAAEA;gBAAOI,MAAM;gBAASvC,MAAM;YAAK;QAClE;IACF;IAEA,MAAM2B,SAAStC,iBACbF,eAAeyC,YAAY,CAAClB;YAE1Bd;QADAK,QAAQ;SACRL,uBAAAA,OAAO0C,YAAY,cAAnB1C,2CAAAA,0BAAAA,QAAsBc,GAAG;YAAEyB,OAAOzB;YAAG6B,MAAM;YAASvC,MAAM;QAAM;IAClE;IAGF,MAAM,CAACwC,YAAYC,UAAU,GAAGhD,sBAA4C;QAC1EI;QACA6C,aAAa9C,OAAO8C,WAAW;IACjC;IAEA,MAAMC,YAAYrD,MAAM,mBAAkBM,uBAAAA,OAAOgD,YAAY,cAAnBhD,2CAAAA,qBAAqB2B,EAAE;IACjE,MAAMsB,qCAAuB,oBAACrD;QAAqBe,mBAAmBA;;IACtE,MAAMuC,6BACJ,oBAAC9D;QACE,GAAGY,OAAOgD,YAAY;QACtB,GAAGlB,yBAAyBqB,iBAAiB;QAC9CxB,IAAIoB;QACJZ,KAAKxC,cAAcmC,yBAAyBqB,iBAAiB,CAAChB,GAAG,EAAES,aAAY5C,wBAAAA,OAAOgD,YAAY,cAAnBhD,4CAAAA,sBAAqBmC,GAAG;;IAG3G,MAAMiB,wBACJ,oBAAC9D;QAAoB+D,SAASjD;qBAC5B,oBAACkD;QAAKC,aAAWnD,OAAO2C,YAAYzB;OACjClB,QAASJ,CAAAA,OAAOwD,MAAM,GAAGN,6BAAe,oBAACpD;QAAO2D,WAAWzD,OAAOyD,SAAS;OAAGP,aAAqB;IAK1G,OAAO;QACLQ,eAAeN;QACfH;QACAZ,cAAc;YACZF,KAAKC;YACLlB;YACAoB;YACAL,WAAWC;YACXH;QACF;QACA4B,cAAcd;IAChB;AACF"}
package/lib/index.js DELETED
@@ -1,2 +0,0 @@
1
- export { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionalityV2';
2
- export { Option, optionClassNames, renderOption_unstable, useOption_unstable, useInputListboxOptionStyles_unstable } from '@fluentui-copilot/react-input-listbox';
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionalityV2';\nexport type {\n OnOpenChangeData,\n UsePromptListboxFunctionalityParams,\n UsePromptListboxFunctionality,\n} from './components/utils/usePromptListboxFunctionalityV2';\n\nexport type {\n ActiveOptionChangeData,\n OptionProps,\n OptionSlots,\n OptionState,\n OptionValue,\n OptionOnSelectData,\n OverrideActionHandler,\n OverrideActionHandlerOptions,\n OverrideActionHandlerResult,\n} from '@fluentui-copilot/react-input-listbox';\nexport {\n Option,\n optionClassNames,\n renderOption_unstable,\n useOption_unstable,\n useInputListboxOptionStyles_unstable,\n} from '@fluentui-copilot/react-input-listbox';\n"],"names":["usePromptListboxFunctionality","Option","optionClassNames","renderOption_unstable","useOption_unstable","useInputListboxOptionStyles_unstable"],"rangeMappings":";","mappings":"AAAA,SAASA,6BAA6B,QAAQ,qDAAqD;AAkBnG,SACEC,MAAM,EACNC,gBAAgB,EAChBC,qBAAqB,EACrBC,kBAAkB,EAClBC,oCAAoC,QAC/B,wCAAwC"}
@@ -1,43 +0,0 @@
1
- import { $isSentinelNode } from '@fluentui-copilot/chat-input-plugins';
2
- import { SELECTION_CHANGE_COMMAND, $getSelection, useLexicalComposerContext, $isRangeSelection, $isElementNode, COMMAND_PRIORITY_HIGH } from '@fluentui-copilot/react-text-editor';
3
- import * as React from 'react';
4
- export const CursorPositionPlugin = ({ setCursorPosition })=>{
5
- const [editor] = useLexicalComposerContext();
6
- React.useEffect(()=>{
7
- const $selectionChangeHandler = ()=>{
8
- const selection = $getSelection();
9
- // If selection is null, the cursor is not active in the editor and we should just noop
10
- if (selection === null || !$isRangeSelection(selection) || !selection.isCollapsed()) {
11
- setCursorPosition('between-text');
12
- return false;
13
- }
14
- // Should only be one node in the selection because the selection is collapsed
15
- const selectedNode = selection.getNodes().at(0);
16
- // If there's no selected node, focus isn't in the editor
17
- if (!selectedNode) {
18
- return false;
19
- }
20
- // If there are no leaf nodes, the paragraph node will be selected
21
- if ($isElementNode(selectedNode)) {
22
- setCursorPosition('start-end');
23
- return false;
24
- } else if ($isSentinelNode(selectedNode) && !selectedNode.getNextSibling()) {
25
- setCursorPosition('end');
26
- return false;
27
- } else if ($isSentinelNode(selectedNode.getNextSibling()) && selection.focus.offset === selectedNode.getTextContentSize()) {
28
- setCursorPosition('end');
29
- return false;
30
- } else if (selectedNode.getPreviousSibling() === null && selection.focus.offset === 0) {
31
- setCursorPosition('start');
32
- return false;
33
- }
34
- setCursorPosition('between-text');
35
- return false;
36
- };
37
- return editor.registerCommand(SELECTION_CHANGE_COMMAND, $selectionChangeHandler, COMMAND_PRIORITY_HIGH);
38
- }, [
39
- editor,
40
- setCursorPosition
41
- ]);
42
- return null;
43
- };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["CursorPositionPlugin.ts"],"sourcesContent":["import { $isSentinelNode } from '@fluentui-copilot/chat-input-plugins';\nimport {\n SELECTION_CHANGE_COMMAND,\n $getSelection,\n useLexicalComposerContext,\n $isRangeSelection,\n $isElementNode,\n COMMAND_PRIORITY_HIGH,\n} from '@fluentui-copilot/react-text-editor';\nimport * as React from 'react';\n\n/**\n * Position the cursor is in based on it's content. The goal\n * is to track whether the cursor is at the end of the input\n * or between text.\n */\nexport type CursorPosition = 'start' | 'between-text' | 'end' | 'start-end';\n\nexport type CursorPositionPluginProps = {\n setCursorPosition: (position: CursorPosition) => void;\n};\n\nexport const CursorPositionPlugin: React.FunctionComponent<CursorPositionPluginProps> = ({ setCursorPosition }) => {\n const [editor] = useLexicalComposerContext();\n\n React.useEffect(() => {\n const $selectionChangeHandler = () => {\n const selection = $getSelection();\n // If selection is null, the cursor is not active in the editor and we should just noop\n if (selection === null || !$isRangeSelection(selection) || !selection.isCollapsed()) {\n setCursorPosition('between-text');\n return false;\n }\n\n // Should only be one node in the selection because the selection is collapsed\n const selectedNode = selection.getNodes().at(0);\n // If there's no selected node, focus isn't in the editor\n if (!selectedNode) {\n return false;\n }\n\n // If there are no leaf nodes, the paragraph node will be selected\n if ($isElementNode(selectedNode)) {\n setCursorPosition('start-end');\n return false;\n }\n\n // if the selection node is a sentinel and it matches the sentinel at the end\n else if ($isSentinelNode(selectedNode) && !selectedNode.getNextSibling()) {\n setCursorPosition('end');\n return false;\n }\n\n // else if the selection node is not a sentinel, check that the next sibling node is a sentinel\n // and check if the focus offset is in the last position of the node.\n else if (\n $isSentinelNode(selectedNode.getNextSibling()) &&\n selection.focus.offset === selectedNode.getTextContentSize()\n ) {\n setCursorPosition('end');\n return false;\n }\n\n // else if the selection node is not at the end and is not a sentinel, check if there's a previous\n // sibling and that we are at the start. If that's the case we are at the start.\n else if (selectedNode.getPreviousSibling() === null && selection.focus.offset === 0) {\n setCursorPosition('start');\n return false;\n }\n\n setCursorPosition('between-text');\n return false;\n };\n\n return editor.registerCommand(SELECTION_CHANGE_COMMAND, $selectionChangeHandler, COMMAND_PRIORITY_HIGH);\n }, [editor, setCursorPosition]);\n\n return null;\n};\n"],"names":["$isSentinelNode","SELECTION_CHANGE_COMMAND","$getSelection","useLexicalComposerContext","$isRangeSelection","$isElementNode","COMMAND_PRIORITY_HIGH","React","CursorPositionPlugin","setCursorPosition","editor","useEffect","$selectionChangeHandler","selection","isCollapsed","selectedNode","getNodes","at","getNextSibling","focus","offset","getTextContentSize","getPreviousSibling","registerCommand"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,eAAe,QAAQ,uCAAuC;AACvE,SACEC,wBAAwB,EACxBC,aAAa,EACbC,yBAAyB,EACzBC,iBAAiB,EACjBC,cAAc,EACdC,qBAAqB,QAChB,sCAAsC;AAC7C,YAAYC,WAAW,QAAQ;AAa/B,OAAO,MAAMC,uBAA2E,CAAC,EAAEC,iBAAiB,EAAE;IAC5G,MAAM,CAACC,OAAO,GAAGP;IAEjBI,MAAMI,SAAS,CAAC;QACd,MAAMC,0BAA0B;YAC9B,MAAMC,YAAYX;YAClB,uFAAuF;YACvF,IAAIW,cAAc,QAAQ,CAACT,kBAAkBS,cAAc,CAACA,UAAUC,WAAW,IAAI;gBACnFL,kBAAkB;gBAClB,OAAO;YACT;YAEA,8EAA8E;YAC9E,MAAMM,eAAeF,UAAUG,QAAQ,GAAGC,EAAE,CAAC;YAC7C,yDAAyD;YACzD,IAAI,CAACF,cAAc;gBACjB,OAAO;YACT;YAEA,kEAAkE;YAClE,IAAIV,eAAeU,eAAe;gBAChCN,kBAAkB;gBAClB,OAAO;YACT,OAGK,IAAIT,gBAAgBe,iBAAiB,CAACA,aAAaG,cAAc,IAAI;gBACxET,kBAAkB;gBAClB,OAAO;YACT,OAIK,IACHT,gBAAgBe,aAAaG,cAAc,OAC3CL,UAAUM,KAAK,CAACC,MAAM,KAAKL,aAAaM,kBAAkB,IAC1D;gBACAZ,kBAAkB;gBAClB,OAAO;YACT,OAIK,IAAIM,aAAaO,kBAAkB,OAAO,QAAQT,UAAUM,KAAK,CAACC,MAAM,KAAK,GAAG;gBACnFX,kBAAkB;gBAClB,OAAO;YACT;YAEAA,kBAAkB;YAClB,OAAO;QACT;QAEA,OAAOC,OAAOa,eAAe,CAACtB,0BAA0BW,yBAAyBN;IACnF,GAAG;QAACI;QAAQD;KAAkB;IAE9B,OAAO;AACT,EAAE"}
@@ -1,65 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "PromptListboxMotion", {
6
- enumerable: true,
7
- get: function() {
8
- return PromptListboxMotion;
9
- }
10
- });
11
- const _reactcomponents = require("@fluentui/react-components");
12
- const collapseMotion = ({ element })=>{
13
- const fromOpacity = 0;
14
- const toOpacity = 1;
15
- const fromHeight = '0';
16
- const toHeight = `${element.scrollHeight}px`;
17
- const overflow = 'hidden';
18
- const duration = _reactcomponents.motionTokens.durationNormal;
19
- const easing = _reactcomponents.motionTokens.curveEasyEaseMax;
20
- const enterKeyframes = [
21
- {
22
- opacity: fromOpacity,
23
- maxHeight: fromHeight,
24
- overflow
25
- },
26
- // Transition to the height of the content, at 99.99% of the duration.
27
- {
28
- opacity: toOpacity,
29
- maxHeight: toHeight,
30
- offset: 0.9999,
31
- overflow
32
- },
33
- // On completion, remove the maxHeight because the content might need to expand later.
34
- {
35
- opacity: toOpacity,
36
- maxHeight: 'unset',
37
- overflow
38
- }
39
- ];
40
- const exitKeyframes = [
41
- {
42
- opacity: toOpacity,
43
- maxHeight: toHeight,
44
- overflow
45
- },
46
- {
47
- opacity: fromOpacity,
48
- maxHeight: fromHeight,
49
- overflow
50
- }
51
- ];
52
- return {
53
- enter: {
54
- duration,
55
- easing,
56
- keyframes: enterKeyframes
57
- },
58
- exit: {
59
- duration,
60
- easing,
61
- keyframes: exitKeyframes
62
- }
63
- };
64
- };
65
- const PromptListboxMotion = (0, _reactcomponents.createPresenceComponent)(collapseMotion);
@@ -1 +0,0 @@
1
- {"version":3,"sources":["PromptListboxMotion.ts"],"sourcesContent":["import { createPresenceComponent, motionTokens } from '@fluentui/react-components';\nimport type { PresenceMotionFn } from '@fluentui/react-components';\n\nconst collapseMotion: PresenceMotionFn = ({ element }) => {\n const fromOpacity = 0;\n const toOpacity = 1;\n const fromHeight = '0';\n const toHeight = `${element.scrollHeight}px`;\n const overflow = 'hidden';\n\n const duration = motionTokens.durationNormal;\n const easing = motionTokens.curveEasyEaseMax;\n\n const enterKeyframes = [\n { opacity: fromOpacity, maxHeight: fromHeight, overflow },\n // Transition to the height of the content, at 99.99% of the duration.\n { opacity: toOpacity, maxHeight: toHeight, offset: 0.9999, overflow },\n // On completion, remove the maxHeight because the content might need to expand later.\n { opacity: toOpacity, maxHeight: 'unset', overflow },\n ];\n\n const exitKeyframes = [\n { opacity: toOpacity, maxHeight: toHeight, overflow },\n { opacity: fromOpacity, maxHeight: fromHeight, overflow },\n ];\n\n return {\n enter: { duration, easing, keyframes: enterKeyframes },\n exit: { duration, easing, keyframes: exitKeyframes },\n };\n};\n\nexport const PromptListboxMotion: ReturnType<typeof createPresenceComponent<{}>> =\n createPresenceComponent(collapseMotion);\n"],"names":["PromptListboxMotion","collapseMotion","element","fromOpacity","toOpacity","fromHeight","toHeight","scrollHeight","overflow","duration","motionTokens","durationNormal","easing","curveEasyEaseMax","enterKeyframes","opacity","maxHeight","offset","exitKeyframes","enter","keyframes","exit","createPresenceComponent"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAgCaA;;;eAAAA;;;iCAhCyC;AAGtD,MAAMC,iBAAmC,CAAC,EAAEC,OAAO,EAAE;IACnD,MAAMC,cAAc;IACpB,MAAMC,YAAY;IAClB,MAAMC,aAAa;IACnB,MAAMC,WAAW,CAAC,EAAEJ,QAAQK,YAAY,CAAC,EAAE,CAAC;IAC5C,MAAMC,WAAW;IAEjB,MAAMC,WAAWC,6BAAAA,CAAaC,cAAc;IAC5C,MAAMC,SAASF,6BAAAA,CAAaG,gBAAgB;IAE5C,MAAMC,iBAAiB;QACrB;YAAEC,SAASZ;YAAaa,WAAWX;YAAYG;QAAS;QACxD,sEAAsE;QACtE;YAAEO,SAASX;YAAWY,WAAWV;YAAUW,QAAQ;YAAQT;QAAS;QACpE,sFAAsF;QACtF;YAAEO,SAASX;YAAWY,WAAW;YAASR;QAAS;KACpD;IAED,MAAMU,gBAAgB;QACpB;YAAEH,SAASX;YAAWY,WAAWV;YAAUE;QAAS;QACpD;YAAEO,SAASZ;YAAaa,WAAWX;YAAYG;QAAS;KACzD;IAED,OAAO;QACLW,OAAO;YAAEV;YAAUG;YAAQQ,WAAWN;QAAe;QACrDO,MAAM;YAAEZ;YAAUG;YAAQQ,WAAWF;QAAc;IACrD;AACF;AAEO,MAAMlB,sBACXsB,IAAAA,wCAAAA,EAAwBrB"}
@@ -1,36 +0,0 @@
1
- // Brought from Fluent UI
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "useListboxPositioning", {
7
- enumerable: true,
8
- get: function() {
9
- return useListboxPositioning;
10
- }
11
- });
12
- const _reactpositioning = require("@fluentui/react-positioning");
13
- function useListboxPositioning(props) {
14
- const { positioning, fluid } = props;
15
- const fallbackPositions = [
16
- 'below'
17
- ];
18
- // popper options
19
- const popperOptions = {
20
- position: 'below',
21
- align: 'start',
22
- offset: {
23
- crossAxis: 0,
24
- mainAxis: 2
25
- },
26
- fallbackPositions: fallbackPositions,
27
- matchTargetSize: fluid ? 'width' : undefined,
28
- autoSize: true,
29
- ...(0, _reactpositioning.resolvePositioningShorthand)(positioning)
30
- };
31
- const { containerRef: listboxRef, targetRef: anchorRef } = (0, _reactpositioning.usePositioning)(popperOptions);
32
- return [
33
- listboxRef,
34
- anchorRef
35
- ];
36
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["useListboxPositioning.ts"],"sourcesContent":["// Brought from Fluent UI\n\nimport { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';\nimport type * as React from 'react';\nimport type { UsePromptListboxFunctionalityParams } from './usePromptListboxFunctionalityV2';\nimport type { PositioningShorthandValue } from '@fluentui/react-positioning';\n\nexport function useListboxPositioning<AnchorElementType extends HTMLElement = HTMLSpanElement>(\n props: Pick<UsePromptListboxFunctionalityParams, 'fluid' | 'positioning'>,\n): [listboxRef: React.RefObject<HTMLSpanElement | null>, anchorRef: React.RefObject<AnchorElementType | null>] {\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 autoSize: true,\n ...resolvePositioningShorthand(positioning),\n };\n\n const { containerRef: listboxRef, targetRef: anchorRef } = usePositioning(popperOptions);\n\n return [listboxRef, anchorRef];\n}\n"],"names":["useListboxPositioning","props","positioning","fluid","fallbackPositions","popperOptions","position","align","offset","crossAxis","mainAxis","matchTargetSize","undefined","autoSize","resolvePositioningShorthand","containerRef","listboxRef","targetRef","anchorRef","usePositioning"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,yBAAyB;;;;;+BAOTA;;;eAAAA;;;kCAL4C;AAKrD,SAASA,sBACdC,KAAyE;IAEzE,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;QAC9CC,UAAU;QACV,GAAGC,IAAAA,6CAAAA,EAA4BZ,YAAY;IAC7C;IAEA,MAAM,EAAEa,cAAcC,UAAU,EAAEC,WAAWC,SAAS,EAAE,GAAGC,IAAAA,gCAAAA,EAAed;IAE1E,OAAO;QAACW;QAAYE;KAAU;AAChC"}
@@ -1,135 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "usePromptListboxFunctionality", {
6
- enumerable: true,
7
- get: function() {
8
- return usePromptListboxFunctionality;
9
- }
10
- });
11
- const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
- const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
- const _reactinputlistbox = require("@fluentui-copilot/react-input-listbox");
14
- const _PromptListboxMotion = require("../motion/PromptListboxMotion");
15
- const _reactutilities = require("@fluentui/react-utilities");
16
- const _CursorPositionPlugin = require("../../plugins/CursorPositionPlugin");
17
- const _useListboxPositioning = require("./useListboxPositioning");
18
- const _reactcomponents = require("@fluentui/react-components");
19
- function usePromptListboxFunctionality(params) {
20
- var _params_listboxProps, _params_listboxProps1;
21
- const { fluid = false, allowArrowUpNavigation = false, onSelectionModeChange } = params;
22
- const [open, setOpen] = (0, _reactutilities.useControllableState)({
23
- state: params.open,
24
- defaultState: params.defaultOpen,
25
- initialState: false
26
- });
27
- const [cursorPosition, setCursorPosition] = _react.useState('end');
28
- const overrideActionHandler = (e, { activeOption, action, activeDescendantController, isInSelectionMode })=>{
29
- var _params_overrideActionHandler;
30
- const atStart = allowArrowUpNavigation && (cursorPosition === 'start' || cursorPosition === 'start-end');
31
- const atEnd = cursorPosition === 'end' || cursorPosition === 'start-end';
32
- let newAction = undefined;
33
- let newIsInSelection = undefined;
34
- const firstOption = activeDescendantController.first({
35
- passive: true
36
- });
37
- switch(action){
38
- case 'Next':
39
- if (!isInSelectionMode && !atEnd) {
40
- newAction = 'Type';
41
- newIsInSelection = false;
42
- }
43
- break;
44
- case 'Previous':
45
- if (!isInSelectionMode && !atStart) {
46
- newAction = 'Type';
47
- newIsInSelection = false;
48
- } else if (isInSelectionMode && !allowArrowUpNavigation && atEnd && activeOption !== undefined && activeOption.id === firstOption) {
49
- newAction = 'Type';
50
- newIsInSelection = false;
51
- e.preventDefault();
52
- }
53
- break;
54
- case 'First':
55
- case 'Last':
56
- case 'PageDown':
57
- case 'PageUp':
58
- if (!isInSelectionMode) {
59
- newAction = 'Type';
60
- newIsInSelection = false;
61
- }
62
- break;
63
- }
64
- const userOverrides = (_params_overrideActionHandler = params.overrideActionHandler) === null || _params_overrideActionHandler === void 0 ? void 0 : _params_overrideActionHandler.call(params, e, {
65
- activeOption,
66
- action,
67
- activeDescendantController,
68
- isInSelectionMode
69
- });
70
- return {
71
- action: newAction,
72
- isInSelectionMode: newIsInSelection,
73
- ...userOverrides
74
- };
75
- };
76
- const baseListboxFunctionality = (0, _reactinputlistbox.useInputListboxFunctionality)({
77
- ...params,
78
- onSelectionModeChange,
79
- overrideActionHandler
80
- });
81
- const { onBlur: baseOnBlur, onKeyDown: baseOnKeyDown, ref: triggerRef, isInSelectionMode } = baseListboxFunctionality.triggerProps;
82
- const onFocus = (event)=>{
83
- if (event.target === event.currentTarget) {
84
- var _params_onOpenChange;
85
- setOpen(true);
86
- (_params_onOpenChange = params.onOpenChange) === null || _params_onOpenChange === void 0 ? void 0 : _params_onOpenChange.call(params, event, {
87
- event,
88
- type: 'focus',
89
- open: true
90
- });
91
- }
92
- };
93
- const onBlur = (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(baseOnBlur, (e)=>{
94
- var _params_onOpenChange;
95
- setOpen(false);
96
- (_params_onOpenChange = params.onOpenChange) === null || _params_onOpenChange === void 0 ? void 0 : _params_onOpenChange.call(params, e, {
97
- event: e,
98
- type: 'focus',
99
- open: false
100
- });
101
- }));
102
- const [listboxRef, anchorRef] = (0, _useListboxPositioning.useListboxPositioning)({
103
- fluid,
104
- positioning: params.positioning
105
- });
106
- const listboxId = (0, _reactutilities.useId)('prompt-listbox', (_params_listboxProps = params.listboxProps) === null || _params_listboxProps === void 0 ? void 0 : _params_listboxProps.id);
107
- const cursorPositionPlugin = /*#__PURE__*/ _react.createElement(_CursorPositionPlugin.CursorPositionPlugin, {
108
- setCursorPosition: setCursorPosition
109
- });
110
- const innerListbox = /*#__PURE__*/ _react.createElement(_reactinputlistbox.InputListbox, {
111
- ...params.listboxProps,
112
- ...baseListboxFunctionality.inputListboxProps,
113
- id: listboxId,
114
- ref: (0, _reactutilities.useMergedRefs)(baseListboxFunctionality.inputListboxProps.ref, listboxRef, (_params_listboxProps1 = params.listboxProps) === null || _params_listboxProps1 === void 0 ? void 0 : _params_listboxProps1.ref)
115
- });
116
- const listbox = /*#__PURE__*/ _react.createElement(_PromptListboxMotion.PromptListboxMotion, {
117
- visible: open
118
- }, /*#__PURE__*/ _react.createElement("span", {
119
- "aria-owns": open ? listboxId : undefined
120
- }, open && (params.inline ? innerListbox : /*#__PURE__*/ _react.createElement(_reactcomponents.Portal, {
121
- mountNode: params.mountNode
122
- }, innerListbox))));
123
- return {
124
- promptListbox: listbox,
125
- cursorPositionPlugin,
126
- triggerProps: {
127
- ref: triggerRef,
128
- isInSelectionMode,
129
- onFocus,
130
- onKeyDown: baseOnKeyDown,
131
- onBlur
132
- },
133
- containerRef: anchorRef
134
- };
135
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["usePromptListboxFunctionalityV2.tsx"],"sourcesContent":["import * as React from 'react';\nimport { InputListbox, useInputListboxFunctionality } from '@fluentui-copilot/react-input-listbox';\nimport { PromptListboxMotion } from '../motion/PromptListboxMotion';\nimport {\n mergeCallbacks,\n useControllableState,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { CursorPositionPlugin } from '../../plugins/CursorPositionPlugin';\nimport { useListboxPositioning } from './useListboxPositioning';\nimport { Portal } from '@fluentui/react-components';\nimport type { JSXElement } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type {\n InputListboxAction,\n InputListboxProps,\n UseInputListboxFunctionalityParams,\n OverrideActionHandler,\n} from '@fluentui-copilot/react-input-listbox';\nimport type { PortalProps } from '@fluentui/react-components';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\nimport type { PositioningShorthand } from '@fluentui/react-positioning';\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\nexport type UsePromptListboxFunctionalityParams = UseInputListboxFunctionalityParams & {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n positioning?: PositioningShorthand;\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 /**\n * Props to be passed to the InputListbox component\n */\n listboxProps?: Partial<InputListboxProps> & {\n ref?: React.RefObject<HTMLDivElement | null>;\n };\n\n /**\n * Whether to allow reaching the listbox options by arrowing up at the start of the input.\n * Note, this prop is meant to be used with the following positioning props:\n * ```ts\n * usePromptListboxFunctionality({\n * positioning: {\n * position: 'above',\n * fallbackPositions: ['above']\n * }\n * });\n * ```\n * This is useful when using PromptListbox with other components such as ChatInput since\n * the input will always stay at the bottom therefore the listbox would always get cut.\n *\n * @default false\n */\n allowArrowUpNavigation?: boolean;\n\n /**\n * Whether to render the listbox inline or use a portal.\n */\n inline?: boolean;\n} & Pick<PortalProps, 'mountNode'>;\n\nexport type UsePromptListboxFunctionality<ContainerElementType extends HTMLElement> = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSXElement;\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.MutableRefObject<HTMLSpanElement | null>;\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 /**\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 containerRef: React.MutableRefObject<ContainerElementType | null>;\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: JSXElement;\n};\n\nexport function usePromptListboxFunctionality<\n TriggerElementType extends HTMLElement = HTMLSpanElement,\n ContainerElementType extends HTMLElement = HTMLDivElement,\n>(params: UsePromptListboxFunctionalityParams): UsePromptListboxFunctionality<ContainerElementType> {\n const { fluid = false, allowArrowUpNavigation = false, onSelectionModeChange } = params;\n const [open, setOpen] = useControllableState({\n state: params.open,\n defaultState: params.defaultOpen,\n initialState: false,\n });\n const [cursorPosition, setCursorPosition] = React.useState<CursorPosition>('end');\n\n const overrideActionHandler: OverrideActionHandler = (\n e,\n { activeOption, action, activeDescendantController, isInSelectionMode },\n ) => {\n const atStart = allowArrowUpNavigation && (cursorPosition === 'start' || cursorPosition === 'start-end');\n const atEnd = cursorPosition === 'end' || cursorPosition === 'start-end';\n let newAction: InputListboxAction | undefined = undefined;\n let newIsInSelection: boolean | undefined = undefined;\n const firstOption = activeDescendantController.first({ passive: true });\n\n switch (action) {\n case 'Next':\n if (!isInSelectionMode && !atEnd) {\n newAction = 'Type';\n newIsInSelection = false;\n }\n break;\n case 'Previous':\n if (!isInSelectionMode && !atStart) {\n newAction = 'Type';\n newIsInSelection = false;\n } else if (\n isInSelectionMode &&\n !allowArrowUpNavigation &&\n atEnd &&\n activeOption !== undefined &&\n activeOption.id === firstOption\n ) {\n newAction = 'Type';\n newIsInSelection = false;\n e.preventDefault();\n }\n break;\n case 'First':\n case 'Last':\n case 'PageDown':\n case 'PageUp':\n if (!isInSelectionMode) {\n newAction = 'Type';\n newIsInSelection = false;\n }\n break;\n }\n\n const userOverrides = params.overrideActionHandler?.(e, {\n activeOption,\n action,\n activeDescendantController,\n isInSelectionMode,\n });\n\n return { action: newAction, isInSelectionMode: newIsInSelection, ...userOverrides };\n };\n\n const baseListboxFunctionality = useInputListboxFunctionality<TriggerElementType>({\n ...params,\n onSelectionModeChange,\n overrideActionHandler,\n });\n const {\n onBlur: baseOnBlur,\n onKeyDown: baseOnKeyDown,\n ref: triggerRef,\n isInSelectionMode,\n } = baseListboxFunctionality.triggerProps;\n\n const onFocus = (event: React.FocusEvent<HTMLSpanElement>) => {\n if (event.target === event.currentTarget) {\n setOpen(true);\n params.onOpenChange?.(event, { event, type: 'focus', open: true });\n }\n };\n\n const onBlur = useEventCallback(\n mergeCallbacks(baseOnBlur, (e: React.FocusEvent<TriggerElementType>) => {\n setOpen(false);\n params.onOpenChange?.(e, { event: e, type: 'focus', open: false });\n }),\n );\n\n const [listboxRef, anchorRef] = useListboxPositioning<ContainerElementType>({\n fluid,\n positioning: params.positioning,\n });\n\n const listboxId = useId('prompt-listbox', params.listboxProps?.id);\n const cursorPositionPlugin = <CursorPositionPlugin setCursorPosition={setCursorPosition} />;\n const innerListbox = (\n <InputListbox\n {...params.listboxProps}\n {...baseListboxFunctionality.inputListboxProps}\n id={listboxId}\n ref={useMergedRefs(baseListboxFunctionality.inputListboxProps.ref, listboxRef, params.listboxProps?.ref)}\n />\n );\n const listbox = (\n <PromptListboxMotion visible={open}>\n <span aria-owns={open ? listboxId : undefined}>\n {open && (params.inline ? innerListbox : <Portal mountNode={params.mountNode}>{innerListbox}</Portal>)}\n </span>\n </PromptListboxMotion>\n );\n\n return {\n promptListbox: listbox,\n cursorPositionPlugin,\n triggerProps: {\n ref: triggerRef,\n isInSelectionMode,\n onFocus,\n onKeyDown: baseOnKeyDown,\n onBlur,\n },\n containerRef: anchorRef,\n };\n}\n"],"names":["usePromptListboxFunctionality","params","fluid","allowArrowUpNavigation","onSelectionModeChange","open","setOpen","useControllableState","state","defaultState","defaultOpen","initialState","cursorPosition","setCursorPosition","React","useState","overrideActionHandler","e","activeOption","action","activeDescendantController","isInSelectionMode","atStart","atEnd","newAction","undefined","newIsInSelection","firstOption","first","passive","id","preventDefault","userOverrides","baseListboxFunctionality","useInputListboxFunctionality","onBlur","baseOnBlur","onKeyDown","baseOnKeyDown","ref","triggerRef","triggerProps","onFocus","event","target","currentTarget","onOpenChange","type","useEventCallback","mergeCallbacks","listboxRef","anchorRef","useListboxPositioning","positioning","listboxId","useId","listboxProps","cursorPositionPlugin","createElement","CursorPositionPlugin","innerListbox","InputListbox","inputListboxProps","useMergedRefs","listbox","PromptListboxMotion","visible","span","aria-owns","inline","Portal","mountNode","promptListbox","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAgHgBA;;;eAAAA;;;;iEAhHO;mCACoC;qCACvB;gCAO7B;sCAC8B;uCACC;iCACf;AAoGhB,SAASA,8BAGdC,MAA2C;QA8FDA,sBAOyCA;IApGnF,MAAM,EAAEC,QAAQ,KAAK,EAAEC,yBAAyB,KAAK,EAAEC,qBAAqB,EAAE,GAAGH;IACjF,MAAM,CAACI,MAAMC,QAAQ,GAAGC,IAAAA,oCAAAA,EAAqB;QAC3CC,OAAOP,OAAOI,IAAI;QAClBI,cAAcR,OAAOS,WAAW;QAChCC,cAAc;IAChB;IACA,MAAM,CAACC,gBAAgBC,kBAAkB,GAAGC,OAAMC,QAAQ,CAAiB;IAE3E,MAAMC,wBAA+C,CACnDC,GACA,EAAEC,YAAY,EAAEC,MAAM,EAAEC,0BAA0B,EAAEC,iBAAiB,EAAE;YA0CjDpB;QAxCtB,MAAMqB,UAAUnB,0BAA2BS,CAAAA,mBAAmB,WAAWA,mBAAmB,WAAA;QAC5F,MAAMW,QAAQX,mBAAmB,SAASA,mBAAmB;QAC7D,IAAIY,YAA4CC;QAChD,IAAIC,mBAAwCD;QAC5C,MAAME,cAAcP,2BAA2BQ,KAAK,CAAC;YAAEC,SAAS;QAAK;QAErE,OAAQV;YACN,KAAK;gBACH,IAAI,CAACE,qBAAqB,CAACE,OAAO;oBAChCC,YAAY;oBACZE,mBAAmB;gBACrB;gBACA;YACF,KAAK;gBACH,IAAI,CAACL,qBAAqB,CAACC,SAAS;oBAClCE,YAAY;oBACZE,mBAAmB;gBACrB,OAAO,IACLL,qBACA,CAAClB,0BACDoB,SACAL,iBAAiBO,aACjBP,aAAaY,EAAE,KAAKH,aACpB;oBACAH,YAAY;oBACZE,mBAAmB;oBACnBT,EAAEc,cAAc;gBAClB;gBACA;YACF,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;gBACH,IAAI,CAACV,mBAAmB;oBACtBG,YAAY;oBACZE,mBAAmB;gBACrB;gBACA;QACJ;QAEA,MAAMM,gBAAAA,AAAgB/B,CAAAA,gCAAAA,OAAOe,qBAAqB,AAArBA,MAAqB,QAA5Bf,kCAAAA,KAAAA,IAAAA,KAAAA,IAAAA,8BAAAA,IAAAA,CAAAA,QAA+BgB,GAAG;YACtDC;YACAC;YACAC;YACAC;QACF;QAEA,OAAO;YAAEF,QAAQK;YAAWH,mBAAmBK;YAAkB,GAAGM,aAAa;QAAC;IACpF;IAEA,MAAMC,2BAA2BC,IAAAA,+CAAAA,EAAiD;QAChF,GAAGjC,MAAM;QACTG;QACAY;IACF;IACA,MAAM,EACJmB,QAAQC,UAAU,EAClBC,WAAWC,aAAa,EACxBC,KAAKC,UAAU,EACfnB,iBAAiB,EAClB,GAAGY,yBAAyBQ,YAAY;IAEzC,MAAMC,UAAU,CAACC;QACf,IAAIA,MAAMC,MAAM,KAAKD,MAAME,aAAa,EAAE;gBAExC5C;YADAK,QAAQ;YACRL,CAAAA,uBAAAA,OAAO6C,YAAY,AAAZA,MAAY,QAAnB7C,yBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,qBAAAA,IAAAA,CAAAA,QAAsB0C,OAAO;gBAAEA;gBAAOI,MAAM;gBAAS1C,MAAM;YAAK;QAClE;IACF;IAEA,MAAM8B,SAASa,IAAAA,gCAAAA,EACbC,IAAAA,8BAAAA,EAAeb,YAAY,CAACnB;YAE1BhB;QADAK,QAAQ;QACRL,CAAAA,uBAAAA,OAAO6C,YAAY,AAAZA,MAAY,QAAnB7C,yBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,qBAAAA,IAAAA,CAAAA,QAAsBgB,GAAG;YAAE0B,OAAO1B;YAAG8B,MAAM;YAAS1C,MAAM;QAAM;IAClE;IAGF,MAAM,CAAC6C,YAAYC,UAAU,GAAGC,IAAAA,4CAAAA,EAA4C;QAC1ElD;QACAmD,aAAapD,OAAOoD,WAAW;IACjC;IAEA,MAAMC,YAAYC,IAAAA,qBAAAA,EAAM,kBAAA,AAAkBtD,CAAAA,uBAAAA,OAAOuD,YAAY,AAAZA,MAAY,QAAnBvD,yBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,qBAAqB6B,EAAE;IACjE,MAAM2B,uBAAAA,WAAAA,GAAuB3C,OAAA4C,aAAA,CAACC,0CAAAA,EAAAA;QAAqB9C,mBAAmBA;;IACtE,MAAM+C,eAAAA,WAAAA,GACJ9C,OAAA4C,aAAA,CAACG,+BAAAA,EAAAA;QACE,GAAG5D,OAAOuD,YAAY;QACtB,GAAGvB,yBAAyB6B,iBAAiB;QAC9ChC,IAAIwB;QACJf,KAAKwB,IAAAA,6BAAAA,EAAc9B,yBAAyB6B,iBAAiB,CAACvB,GAAG,EAAEW,YAAAA,AAAYjD,CAAAA,wBAAAA,OAAOuD,YAAY,AAAZA,MAAY,QAAnBvD,0BAAAA,KAAAA,IAAAA,KAAAA,IAAAA,sBAAqBsC,GAAG;;IAG3G,MAAMyB,UAAAA,WAAAA,GACJlD,OAAA4C,aAAA,CAACO,wCAAAA,EAAAA;QAAoBC,SAAS7D;qBAC5BS,OAAA4C,aAAA,CAACS,QAAAA;QAAKC,aAAW/D,OAAOiD,YAAY7B;OACjCpB,QAASJ,CAAAA,OAAOoE,MAAM,GAAGT,eAAAA,WAAAA,GAAe9C,OAAA4C,aAAA,CAACY,uBAAAA,EAAAA;QAAOC,WAAWtE,OAAOsE,SAAS;OAAGX,aAAAA;IAKrF,OAAO;QACLY,eAAeR;QACfP;QACAhB,cAAc;YACZF,KAAKC;YACLnB;YACAqB;YACAL,WAAWC;YACXH;QACF;QACAsC,cAActB;IAChB;AACF"}
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: all[name]
9
- });
10
- }
11
- _export(exports, {
12
- Option: function() {
13
- return _reactinputlistbox.Option;
14
- },
15
- optionClassNames: function() {
16
- return _reactinputlistbox.optionClassNames;
17
- },
18
- renderOption_unstable: function() {
19
- return _reactinputlistbox.renderOption_unstable;
20
- },
21
- useInputListboxOptionStyles_unstable: function() {
22
- return _reactinputlistbox.useInputListboxOptionStyles_unstable;
23
- },
24
- useOption_unstable: function() {
25
- return _reactinputlistbox.useOption_unstable;
26
- },
27
- usePromptListboxFunctionality: function() {
28
- return _usePromptListboxFunctionalityV2.usePromptListboxFunctionality;
29
- }
30
- });
31
- const _usePromptListboxFunctionalityV2 = require("./components/utils/usePromptListboxFunctionalityV2");
32
- const _reactinputlistbox = require("@fluentui-copilot/react-input-listbox");
@@ -1 +0,0 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionalityV2';\nexport type {\n OnOpenChangeData,\n UsePromptListboxFunctionalityParams,\n UsePromptListboxFunctionality,\n} from './components/utils/usePromptListboxFunctionalityV2';\n\nexport type {\n ActiveOptionChangeData,\n OptionProps,\n OptionSlots,\n OptionState,\n OptionValue,\n OptionOnSelectData,\n OverrideActionHandler,\n OverrideActionHandlerOptions,\n OverrideActionHandlerResult,\n} from '@fluentui-copilot/react-input-listbox';\nexport {\n Option,\n optionClassNames,\n renderOption_unstable,\n useOption_unstable,\n useInputListboxOptionStyles_unstable,\n} from '@fluentui-copilot/react-input-listbox';\n"],"names":["Option","optionClassNames","renderOption_unstable","useInputListboxOptionStyles_unstable","useOption_unstable","usePromptListboxFunctionality"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAmBEA,MAAM;eAANA,yBAAM;;IACNC,gBAAgB;eAAhBA,mCAAgB;;IAChBC,qBAAqB;eAArBA,wCAAqB;;IAErBC,oCAAoC;eAApCA,uDAAoC;;IADpCC,kBAAkB;eAAlBA,qCAAkB;;IAtBXC,6BAA6B;eAA7BA,8DAA6B;;;iDAAQ;mCAwBvC"}
@@ -1,54 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "CursorPositionPlugin", {
6
- enumerable: true,
7
- get: function() {
8
- return CursorPositionPlugin;
9
- }
10
- });
11
- const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
- const _chatinputplugins = require("@fluentui-copilot/chat-input-plugins");
13
- const _reacttexteditor = require("@fluentui-copilot/react-text-editor");
14
- const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
15
- const CursorPositionPlugin = ({ setCursorPosition })=>{
16
- const [editor] = (0, _reacttexteditor.useLexicalComposerContext)();
17
- _react.useEffect(()=>{
18
- const $selectionChangeHandler = ()=>{
19
- const selection = (0, _reacttexteditor.$getSelection)();
20
- // If selection is null, the cursor is not active in the editor and we should just noop
21
- if (selection === null || !(0, _reacttexteditor.$isRangeSelection)(selection) || !selection.isCollapsed()) {
22
- setCursorPosition('between-text');
23
- return false;
24
- }
25
- // Should only be one node in the selection because the selection is collapsed
26
- const selectedNode = selection.getNodes().at(0);
27
- // If there's no selected node, focus isn't in the editor
28
- if (!selectedNode) {
29
- return false;
30
- }
31
- // If there are no leaf nodes, the paragraph node will be selected
32
- if ((0, _reacttexteditor.$isElementNode)(selectedNode)) {
33
- setCursorPosition('start-end');
34
- return false;
35
- } else if ((0, _chatinputplugins.$isSentinelNode)(selectedNode) && !selectedNode.getNextSibling()) {
36
- setCursorPosition('end');
37
- return false;
38
- } else if ((0, _chatinputplugins.$isSentinelNode)(selectedNode.getNextSibling()) && selection.focus.offset === selectedNode.getTextContentSize()) {
39
- setCursorPosition('end');
40
- return false;
41
- } else if (selectedNode.getPreviousSibling() === null && selection.focus.offset === 0) {
42
- setCursorPosition('start');
43
- return false;
44
- }
45
- setCursorPosition('between-text');
46
- return false;
47
- };
48
- return editor.registerCommand(_reacttexteditor.SELECTION_CHANGE_COMMAND, $selectionChangeHandler, _reacttexteditor.COMMAND_PRIORITY_HIGH);
49
- }, [
50
- editor,
51
- setCursorPosition
52
- ]);
53
- return null;
54
- };
@@ -1 +0,0 @@
1
- {"version":3,"sources":["CursorPositionPlugin.ts"],"sourcesContent":["import { $isSentinelNode } from '@fluentui-copilot/chat-input-plugins';\nimport {\n SELECTION_CHANGE_COMMAND,\n $getSelection,\n useLexicalComposerContext,\n $isRangeSelection,\n $isElementNode,\n COMMAND_PRIORITY_HIGH,\n} from '@fluentui-copilot/react-text-editor';\nimport * as React from 'react';\n\n/**\n * Position the cursor is in based on it's content. The goal\n * is to track whether the cursor is at the end of the input\n * or between text.\n */\nexport type CursorPosition = 'start' | 'between-text' | 'end' | 'start-end';\n\nexport type CursorPositionPluginProps = {\n setCursorPosition: (position: CursorPosition) => void;\n};\n\nexport const CursorPositionPlugin: React.FunctionComponent<CursorPositionPluginProps> = ({ setCursorPosition }) => {\n const [editor] = useLexicalComposerContext();\n\n React.useEffect(() => {\n const $selectionChangeHandler = () => {\n const selection = $getSelection();\n // If selection is null, the cursor is not active in the editor and we should just noop\n if (selection === null || !$isRangeSelection(selection) || !selection.isCollapsed()) {\n setCursorPosition('between-text');\n return false;\n }\n\n // Should only be one node in the selection because the selection is collapsed\n const selectedNode = selection.getNodes().at(0);\n // If there's no selected node, focus isn't in the editor\n if (!selectedNode) {\n return false;\n }\n\n // If there are no leaf nodes, the paragraph node will be selected\n if ($isElementNode(selectedNode)) {\n setCursorPosition('start-end');\n return false;\n }\n\n // if the selection node is a sentinel and it matches the sentinel at the end\n else if ($isSentinelNode(selectedNode) && !selectedNode.getNextSibling()) {\n setCursorPosition('end');\n return false;\n }\n\n // else if the selection node is not a sentinel, check that the next sibling node is a sentinel\n // and check if the focus offset is in the last position of the node.\n else if (\n $isSentinelNode(selectedNode.getNextSibling()) &&\n selection.focus.offset === selectedNode.getTextContentSize()\n ) {\n setCursorPosition('end');\n return false;\n }\n\n // else if the selection node is not at the end and is not a sentinel, check if there's a previous\n // sibling and that we are at the start. If that's the case we are at the start.\n else if (selectedNode.getPreviousSibling() === null && selection.focus.offset === 0) {\n setCursorPosition('start');\n return false;\n }\n\n setCursorPosition('between-text');\n return false;\n };\n\n return editor.registerCommand(SELECTION_CHANGE_COMMAND, $selectionChangeHandler, COMMAND_PRIORITY_HIGH);\n }, [editor, setCursorPosition]);\n\n return null;\n};\n"],"names":["CursorPositionPlugin","setCursorPosition","editor","useLexicalComposerContext","React","useEffect","$selectionChangeHandler","selection","$getSelection","$isRangeSelection","isCollapsed","selectedNode","getNodes","at","$isElementNode","$isSentinelNode","getNextSibling","focus","offset","getTextContentSize","getPreviousSibling","registerCommand","SELECTION_CHANGE_COMMAND","COMMAND_PRIORITY_HIGH"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAsBaA;;;eAAAA;;;;kCAtBmB;iCAQzB;iEACgB;AAahB,MAAMA,uBAA2E,CAAC,EAAEC,iBAAiB,EAAE;IAC5G,MAAM,CAACC,OAAO,GAAGC,IAAAA,0CAAAA;IAEjBC,OAAMC,SAAS,CAAC;QACd,MAAMC,0BAA0B;YAC9B,MAAMC,YAAYC,IAAAA,8BAAAA;YAClB,uFAAuF;YACvF,IAAID,cAAc,QAAQ,CAACE,IAAAA,kCAAAA,EAAkBF,cAAc,CAACA,UAAUG,WAAW,IAAI;gBACnFT,kBAAkB;gBAClB,OAAO;YACT;YAEA,8EAA8E;YAC9E,MAAMU,eAAeJ,UAAUK,QAAQ,GAAGC,EAAE,CAAC;YAC7C,yDAAyD;YACzD,IAAI,CAACF,cAAc;gBACjB,OAAO;YACT;YAEA,kEAAkE;YAClE,IAAIG,IAAAA,+BAAAA,EAAeH,eAAe;gBAChCV,kBAAkB;gBAClB,OAAO;YACT,OAGK,IAAIc,IAAAA,iCAAAA,EAAgBJ,iBAAiB,CAACA,aAAaK,cAAc,IAAI;gBACxEf,kBAAkB;gBAClB,OAAO;YACT,OAIK,IACHc,IAAAA,iCAAAA,EAAgBJ,aAAaK,cAAc,OAC3CT,UAAUU,KAAK,CAACC,MAAM,KAAKP,aAAaQ,kBAAkB,IAC1D;gBACAlB,kBAAkB;gBAClB,OAAO;YACT,OAIK,IAAIU,aAAaS,kBAAkB,OAAO,QAAQb,UAAUU,KAAK,CAACC,MAAM,KAAK,GAAG;gBACnFjB,kBAAkB;gBAClB,OAAO;YACT;YAEAA,kBAAkB;YAClB,OAAO;QACT;QAEA,OAAOC,OAAOmB,eAAe,CAACC,yCAAAA,EAA0BhB,yBAAyBiB,sCAAAA;IACnF,GAAG;QAACrB;QAAQD;KAAkB;IAE9B,OAAO;AACT"}