@fluentui-copilot/react-prompt-listbox 0.0.0-nightly-20240816-0407-4f31c87a.1 → 0.0.0-nightly-20240820-0406-cc08f744.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.
Files changed (28) hide show
  1. package/CHANGELOG.json +17 -17
  2. package/CHANGELOG.md +11 -11
  3. package/dist/index.d.ts +0 -6
  4. package/lib/components/utils/dropdownKeyActions.js +5 -5
  5. package/lib/components/utils/dropdownKeyActions.js.map +1 -1
  6. package/lib/components/utils/usePromptListboxFunctionality.js +8 -8
  7. package/lib/components/utils/usePromptListboxFunctionality.js.map +1 -1
  8. package/lib/components/utils/useTriggerKeyDown.js +2 -2
  9. package/lib/components/utils/useTriggerKeyDown.js.map +1 -1
  10. package/lib/index.js +0 -1
  11. package/lib/index.js.map +1 -1
  12. package/lib/plugins/CursorPositionPlugin.js +42 -0
  13. package/lib/plugins/CursorPositionPlugin.js.map +1 -0
  14. package/lib-commonjs/components/utils/dropdownKeyActions.js +5 -5
  15. package/lib-commonjs/components/utils/dropdownKeyActions.js.map +1 -1
  16. package/lib-commonjs/components/utils/usePromptListboxFunctionality.js +7 -7
  17. package/lib-commonjs/components/utils/usePromptListboxFunctionality.js.map +1 -1
  18. package/lib-commonjs/components/utils/useTriggerKeyDown.js +2 -2
  19. package/lib-commonjs/components/utils/useTriggerKeyDown.js.map +1 -1
  20. package/lib-commonjs/index.js +0 -4
  21. package/lib-commonjs/index.js.map +1 -1
  22. package/lib-commonjs/plugins/CursorPositionPlugin.js +53 -0
  23. package/lib-commonjs/plugins/CursorPositionPlugin.js.map +1 -0
  24. package/package.json +8 -8
  25. package/lib/plugins/TextCursorPositionPlugin.js +0 -44
  26. package/lib/plugins/TextCursorPositionPlugin.js.map +0 -1
  27. package/lib-commonjs/plugins/TextCursorPositionPlugin.js +0 -52
  28. package/lib-commonjs/plugins/TextCursorPositionPlugin.js.map +0 -1
package/CHANGELOG.json CHANGED
@@ -2,9 +2,9 @@
2
2
  "name": "@fluentui-copilot/react-prompt-listbox",
3
3
  "entries": [
4
4
  {
5
- "date": "Fri, 16 Aug 2024 04:14:16 GMT",
6
- "tag": "@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20240816-0407-4f31c87a.1",
7
- "version": "0.0.0-nightly-20240816-0407-4f31c87a.1",
5
+ "date": "Tue, 20 Aug 2024 04:13:00 GMT",
6
+ "tag": "@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20240820-0406-cc08f744.1",
7
+ "version": "0.0.0-nightly-20240820-0406-cc08f744.1",
8
8
  "comments": {
9
9
  "prerelease": [
10
10
  {
@@ -16,44 +16,44 @@
16
16
  {
17
17
  "author": "beachball",
18
18
  "package": "@fluentui-copilot/react-prompt-listbox",
19
- "comment": "Bump @fluentui-copilot/chat-input-plugins to v0.0.0-nightly-20240816-0407-4f31c87a.1",
20
- "commit": "52bc7571c6ef0aff09d0e248505c586bc311a06d"
19
+ "comment": "Bump @fluentui-copilot/chat-input-plugins to v0.0.0-nightly-20240820-0406-cc08f744.1",
20
+ "commit": "963d9a780a78694de755ce29635c201c639ce63b"
21
21
  },
22
22
  {
23
23
  "author": "beachball",
24
24
  "package": "@fluentui-copilot/react-prompt-listbox",
25
- "comment": "Bump @fluentui-copilot/react-chat-input-plugins to v0.0.0-nightly-20240816-0407-4f31c87a.1",
26
- "commit": "52bc7571c6ef0aff09d0e248505c586bc311a06d"
25
+ "comment": "Bump @fluentui-copilot/react-chat-input-plugins to v0.0.0-nightly-20240820-0406-cc08f744.1",
26
+ "commit": "963d9a780a78694de755ce29635c201c639ce63b"
27
27
  },
28
28
  {
29
29
  "author": "beachball",
30
30
  "package": "@fluentui-copilot/react-prompt-listbox",
31
- "comment": "Bump @fluentui-copilot/react-editor-input to v0.0.0-nightly-20240816-0407-4f31c87a.1",
32
- "commit": "52bc7571c6ef0aff09d0e248505c586bc311a06d"
31
+ "comment": "Bump @fluentui-copilot/react-editor-input to v0.0.0-nightly-20240820-0406-cc08f744.1",
32
+ "commit": "963d9a780a78694de755ce29635c201c639ce63b"
33
33
  },
34
34
  {
35
35
  "author": "beachball",
36
36
  "package": "@fluentui-copilot/react-prompt-listbox",
37
- "comment": "Bump @fluentui-copilot/react-prompt-input to v0.0.0-nightly-20240816-0407-4f31c87a.1",
38
- "commit": "52bc7571c6ef0aff09d0e248505c586bc311a06d"
37
+ "comment": "Bump @fluentui-copilot/react-prompt-input to v0.0.0-nightly-20240820-0406-cc08f744.1",
38
+ "commit": "963d9a780a78694de755ce29635c201c639ce63b"
39
39
  },
40
40
  {
41
41
  "author": "beachball",
42
42
  "package": "@fluentui-copilot/react-prompt-listbox",
43
- "comment": "Bump @fluentui-copilot/react-provider to v0.0.0-nightly-20240816-0407-4f31c87a.1",
44
- "commit": "52bc7571c6ef0aff09d0e248505c586bc311a06d"
43
+ "comment": "Bump @fluentui-copilot/react-provider to v0.0.0-nightly-20240820-0406-cc08f744.1",
44
+ "commit": "963d9a780a78694de755ce29635c201c639ce63b"
45
45
  },
46
46
  {
47
47
  "author": "beachball",
48
48
  "package": "@fluentui-copilot/react-prompt-listbox",
49
- "comment": "Bump @fluentui-copilot/react-text-editor to v0.0.0-nightly-20240816-0407-4f31c87a.1",
50
- "commit": "52bc7571c6ef0aff09d0e248505c586bc311a06d"
49
+ "comment": "Bump @fluentui-copilot/react-text-editor to v0.0.0-nightly-20240820-0406-cc08f744.1",
50
+ "commit": "963d9a780a78694de755ce29635c201c639ce63b"
51
51
  },
52
52
  {
53
53
  "author": "beachball",
54
54
  "package": "@fluentui-copilot/react-prompt-listbox",
55
- "comment": "Bump @fluentui-copilot/text-editor to v0.0.0-nightly-20240816-0407-4f31c87a.1",
56
- "commit": "52bc7571c6ef0aff09d0e248505c586bc311a06d"
55
+ "comment": "Bump @fluentui-copilot/text-editor to v0.0.0-nightly-20240820-0406-cc08f744.1",
56
+ "commit": "963d9a780a78694de755ce29635c201c639ce63b"
57
57
  }
58
58
  ]
59
59
  }
package/CHANGELOG.md CHANGED
@@ -1,24 +1,24 @@
1
1
  # Change Log - @fluentui-copilot/react-prompt-listbox
2
2
 
3
- This log was last generated on Fri, 16 Aug 2024 04:14:16 GMT and should not be manually modified.
3
+ This log was last generated on Tue, 20 Aug 2024 04:13:00 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## [0.0.0-nightly-20240816-0407-4f31c87a.1](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20240816-0407-4f31c87a.1)
7
+ ## [0.0.0-nightly-20240820-0406-cc08f744.1](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20240820-0406-cc08f744.1)
8
8
 
9
- Fri, 16 Aug 2024 04:14:16 GMT
10
- [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/react-prompt-listbox_v0.0.4..@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20240816-0407-4f31c87a.1)
9
+ Tue, 20 Aug 2024 04:13:00 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentai/compare/@fluentui-copilot/react-prompt-listbox_v0.0.4..@fluentui-copilot/react-prompt-listbox_v0.0.0-nightly-20240820-0406-cc08f744.1)
11
11
 
12
12
  ### Changes
13
13
 
14
14
  - Release nightly ([commit](https://github.com/microsoft/fluentai/commit/not available) by fluentui-internal@service.microsoft.com)
15
- - Bump @fluentui-copilot/chat-input-plugins to v0.0.0-nightly-20240816-0407-4f31c87a.1 ([commit](https://github.com/microsoft/fluentai/commit/52bc7571c6ef0aff09d0e248505c586bc311a06d) by beachball)
16
- - Bump @fluentui-copilot/react-chat-input-plugins to v0.0.0-nightly-20240816-0407-4f31c87a.1 ([commit](https://github.com/microsoft/fluentai/commit/52bc7571c6ef0aff09d0e248505c586bc311a06d) by beachball)
17
- - Bump @fluentui-copilot/react-editor-input to v0.0.0-nightly-20240816-0407-4f31c87a.1 ([commit](https://github.com/microsoft/fluentai/commit/52bc7571c6ef0aff09d0e248505c586bc311a06d) by beachball)
18
- - Bump @fluentui-copilot/react-prompt-input to v0.0.0-nightly-20240816-0407-4f31c87a.1 ([commit](https://github.com/microsoft/fluentai/commit/52bc7571c6ef0aff09d0e248505c586bc311a06d) by beachball)
19
- - Bump @fluentui-copilot/react-provider to v0.0.0-nightly-20240816-0407-4f31c87a.1 ([commit](https://github.com/microsoft/fluentai/commit/52bc7571c6ef0aff09d0e248505c586bc311a06d) by beachball)
20
- - Bump @fluentui-copilot/react-text-editor to v0.0.0-nightly-20240816-0407-4f31c87a.1 ([commit](https://github.com/microsoft/fluentai/commit/52bc7571c6ef0aff09d0e248505c586bc311a06d) by beachball)
21
- - Bump @fluentui-copilot/text-editor to v0.0.0-nightly-20240816-0407-4f31c87a.1 ([commit](https://github.com/microsoft/fluentai/commit/52bc7571c6ef0aff09d0e248505c586bc311a06d) by beachball)
15
+ - Bump @fluentui-copilot/chat-input-plugins to v0.0.0-nightly-20240820-0406-cc08f744.1 ([commit](https://github.com/microsoft/fluentai/commit/963d9a780a78694de755ce29635c201c639ce63b) by beachball)
16
+ - Bump @fluentui-copilot/react-chat-input-plugins to v0.0.0-nightly-20240820-0406-cc08f744.1 ([commit](https://github.com/microsoft/fluentai/commit/963d9a780a78694de755ce29635c201c639ce63b) by beachball)
17
+ - Bump @fluentui-copilot/react-editor-input to v0.0.0-nightly-20240820-0406-cc08f744.1 ([commit](https://github.com/microsoft/fluentai/commit/963d9a780a78694de755ce29635c201c639ce63b) by beachball)
18
+ - Bump @fluentui-copilot/react-prompt-input to v0.0.0-nightly-20240820-0406-cc08f744.1 ([commit](https://github.com/microsoft/fluentai/commit/963d9a780a78694de755ce29635c201c639ce63b) by beachball)
19
+ - Bump @fluentui-copilot/react-provider to v0.0.0-nightly-20240820-0406-cc08f744.1 ([commit](https://github.com/microsoft/fluentai/commit/963d9a780a78694de755ce29635c201c639ce63b) by beachball)
20
+ - Bump @fluentui-copilot/react-text-editor to v0.0.0-nightly-20240820-0406-cc08f744.1 ([commit](https://github.com/microsoft/fluentai/commit/963d9a780a78694de755ce29635c201c639ce63b) by beachball)
21
+ - Bump @fluentui-copilot/text-editor to v0.0.0-nightly-20240820-0406-cc08f744.1 ([commit](https://github.com/microsoft/fluentai/commit/963d9a780a78694de755ce29635c201c639ce63b) by beachball)
22
22
 
23
23
  ## [0.0.3](https://github.com/microsoft/fluentai/tree/@fluentui-copilot/react-prompt-listbox_v0.0.3)
24
24
 
package/dist/index.d.ts CHANGED
@@ -147,12 +147,6 @@ declare type SelectionState = {
147
147
  selectOption: (event: SelectionEvents, option: OptionValue) => void;
148
148
  };
149
149
 
150
- export declare const TextCursorPositionPlugin: React_2.FunctionComponent<TextCursorPositionPluginProps>;
151
-
152
- export declare type TextCursorPositionPluginProps = {
153
- setIsInLastPosition: (isInLastPosition: boolean) => void;
154
- };
155
-
156
150
  /**
157
151
  * Create the state required to render PromptListbox.
158
152
  *
@@ -7,7 +7,7 @@
7
7
  */
8
8
  export function getDropdownActionFromKey(e, options) {
9
9
  const {
10
- isInLastPosition
10
+ cursorPosition
11
11
  } = options;
12
12
  const code = e.key;
13
13
  const {
@@ -26,16 +26,16 @@ export function getDropdownActionFromKey(e, options) {
26
26
  }
27
27
  // navigation interactions
28
28
  if (code === keys.ArrowDown) {
29
- return isInLastPosition ? 'Next' : 'Type';
29
+ return cursorPosition === 'end' ? 'Next' : 'Type';
30
30
  }
31
31
  if (code === keys.ArrowUp) {
32
- return isInLastPosition ? 'Previous' : 'Type';
32
+ return cursorPosition === 'end' ? 'Previous' : 'Type';
33
33
  }
34
34
  if (code === keys.Home) {
35
- return 'First';
35
+ return cursorPosition === 'end' ? 'First' : 'Type';
36
36
  }
37
37
  if (code === keys.End) {
38
- return 'Last';
38
+ return cursorPosition === 'end' ? 'Last' : 'Type';
39
39
  }
40
40
  if (code === keys.PageUp) {
41
41
  return 'PageUp';
@@ -1 +1 @@
1
- {"version":3,"sources":["dropdownKeyActions.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case.\n */\n\nimport * as keys from '@fluentui/keyboard-keys';\nimport type * as React from 'react';\n\n/**\n * enum of actions available in any type of managed dropdown control\n * e.g. combobox, select, datepicker, menu\n */\nexport type DropdownActions =\n | 'CloseSelect'\n | 'First'\n | 'Last'\n | 'Next'\n | 'None'\n | 'PageDown'\n | 'PageUp'\n | 'Previous'\n | 'Select'\n | 'Tab'\n | 'Type';\n\nexport interface DropdownActionOptions {\n open?: boolean;\n multiselect?: boolean;\n isInLastPosition: boolean;\n}\n\n/**\n * Converts a keyboard interaction into a defined action\n */\nexport function getDropdownActionFromKey(\n e: KeyboardEvent | React.KeyboardEvent,\n options: DropdownActionOptions,\n): DropdownActions {\n const { isInLastPosition } = options;\n const code = e.key;\n const { altKey, ctrlKey, key, metaKey } = e;\n\n // typing action occurs whether open or closed\n if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {\n return 'Type';\n }\n\n // select or close actions\n if ((code === keys.ArrowUp && altKey) || code === keys.Enter) {\n return 'CloseSelect';\n }\n\n // navigation interactions\n if (code === keys.ArrowDown) {\n return isInLastPosition ? 'Next' : 'Type';\n }\n if (code === keys.ArrowUp) {\n return isInLastPosition ? 'Previous' : 'Type';\n }\n if (code === keys.Home) {\n return 'First';\n }\n if (code === keys.End) {\n return 'Last';\n }\n if (code === keys.PageUp) {\n return 'PageUp';\n }\n if (code === keys.PageDown) {\n return 'PageDown';\n }\n if (code === keys.Tab) {\n return 'Tab';\n }\n\n // if nothing matched, return none\n return 'None';\n}\n"],"names":["keys","getDropdownActionFromKey","e","options","isInLastPosition","code","key","altKey","ctrlKey","metaKey","length","Space","ArrowUp","Enter","ArrowDown","Home","End","PageUp","PageDown","Tab"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;CAGC,GAED,YAAYA,UAAU,0BAA0B;AA0BhD;;CAEC,GACD,OAAO,SAASC,yBACdC,CAAsC,EACtCC,OAA8B;IAE9B,MAAM,EAAEC,gBAAgB,EAAE,GAAGD;IAC7B,MAAME,OAAOH,EAAEI,GAAG;IAClB,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAEF,GAAG,EAAEG,OAAO,EAAE,GAAGP;IAE1C,8CAA8C;IAC9C,IAAII,IAAII,MAAM,KAAK,KAAKL,SAASL,KAAKW,KAAK,IAAI,CAACJ,UAAU,CAACC,WAAW,CAACC,SAAS;QAC9E,OAAO;IACT;IAEA,0BAA0B;IAC1B,IAAI,AAACJ,SAASL,KAAKY,OAAO,IAAIL,UAAWF,SAASL,KAAKa,KAAK,EAAE;QAC5D,OAAO;IACT;IAEA,0BAA0B;IAC1B,IAAIR,SAASL,KAAKc,SAAS,EAAE;QAC3B,OAAOV,mBAAmB,SAAS;IACrC;IACA,IAAIC,SAASL,KAAKY,OAAO,EAAE;QACzB,OAAOR,mBAAmB,aAAa;IACzC;IACA,IAAIC,SAASL,KAAKe,IAAI,EAAE;QACtB,OAAO;IACT;IACA,IAAIV,SAASL,KAAKgB,GAAG,EAAE;QACrB,OAAO;IACT;IACA,IAAIX,SAASL,KAAKiB,MAAM,EAAE;QACxB,OAAO;IACT;IACA,IAAIZ,SAASL,KAAKkB,QAAQ,EAAE;QAC1B,OAAO;IACT;IACA,IAAIb,SAASL,KAAKmB,GAAG,EAAE;QACrB,OAAO;IACT;IAEA,kCAAkC;IAClC,OAAO;AACT"}
1
+ {"version":3,"sources":["dropdownKeyActions.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case.\n */\n\nimport * as keys from '@fluentui/keyboard-keys';\nimport type * as React from 'react';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\n\n/**\n * enum of actions available in any type of managed dropdown control\n * e.g. combobox, select, datepicker, menu\n */\nexport type DropdownActions =\n | 'CloseSelect'\n | 'First'\n | 'Last'\n | 'Next'\n | 'None'\n | 'PageDown'\n | 'PageUp'\n | 'Previous'\n | 'Select'\n | 'Tab'\n | 'Type';\n\nexport interface DropdownActionOptions {\n open?: boolean;\n multiselect?: boolean;\n cursorPosition: CursorPosition;\n}\n\n/**\n * Converts a keyboard interaction into a defined action\n */\nexport function getDropdownActionFromKey(\n e: KeyboardEvent | React.KeyboardEvent,\n options: DropdownActionOptions,\n): DropdownActions {\n const { cursorPosition } = options;\n const code = e.key;\n const { altKey, ctrlKey, key, metaKey } = e;\n\n // typing action occurs whether open or closed\n if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {\n return 'Type';\n }\n\n // select or close actions\n if ((code === keys.ArrowUp && altKey) || code === keys.Enter) {\n return 'CloseSelect';\n }\n\n // navigation interactions\n if (code === keys.ArrowDown) {\n return cursorPosition === 'end' ? 'Next' : 'Type';\n }\n if (code === keys.ArrowUp) {\n return cursorPosition === 'end' ? 'Previous' : 'Type';\n }\n if (code === keys.Home) {\n return cursorPosition === 'end' ? 'First' : 'Type';\n }\n if (code === keys.End) {\n return cursorPosition === 'end' ? 'Last' : 'Type';\n }\n if (code === keys.PageUp) {\n return 'PageUp';\n }\n if (code === keys.PageDown) {\n return 'PageDown';\n }\n if (code === keys.Tab) {\n return 'Tab';\n }\n\n // if nothing matched, return none\n return 'None';\n}\n"],"names":["keys","getDropdownActionFromKey","e","options","cursorPosition","code","key","altKey","ctrlKey","metaKey","length","Space","ArrowUp","Enter","ArrowDown","Home","End","PageUp","PageDown","Tab"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;CAGC,GAED,YAAYA,UAAU,0BAA0B;AA2BhD;;CAEC,GACD,OAAO,SAASC,yBACdC,CAAsC,EACtCC,OAA8B;IAE9B,MAAM,EAAEC,cAAc,EAAE,GAAGD;IAC3B,MAAME,OAAOH,EAAEI,GAAG;IAClB,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAEF,GAAG,EAAEG,OAAO,EAAE,GAAGP;IAE1C,8CAA8C;IAC9C,IAAII,IAAII,MAAM,KAAK,KAAKL,SAASL,KAAKW,KAAK,IAAI,CAACJ,UAAU,CAACC,WAAW,CAACC,SAAS;QAC9E,OAAO;IACT;IAEA,0BAA0B;IAC1B,IAAI,AAACJ,SAASL,KAAKY,OAAO,IAAIL,UAAWF,SAASL,KAAKa,KAAK,EAAE;QAC5D,OAAO;IACT;IAEA,0BAA0B;IAC1B,IAAIR,SAASL,KAAKc,SAAS,EAAE;QAC3B,OAAOV,mBAAmB,QAAQ,SAAS;IAC7C;IACA,IAAIC,SAASL,KAAKY,OAAO,EAAE;QACzB,OAAOR,mBAAmB,QAAQ,aAAa;IACjD;IACA,IAAIC,SAASL,KAAKe,IAAI,EAAE;QACtB,OAAOX,mBAAmB,QAAQ,UAAU;IAC9C;IACA,IAAIC,SAASL,KAAKgB,GAAG,EAAE;QACrB,OAAOZ,mBAAmB,QAAQ,SAAS;IAC7C;IACA,IAAIC,SAASL,KAAKiB,MAAM,EAAE;QACxB,OAAO;IACT;IACA,IAAIZ,SAASL,KAAKkB,QAAQ,EAAE;QAC1B,OAAO;IACT;IACA,IAAIb,SAASL,KAAKmB,GAAG,EAAE;QACrB,OAAO;IACT;IAEA,kCAAkC;IAClC,OAAO;AACT"}
@@ -2,10 +2,10 @@ import * as React from 'react';
2
2
  import { useActiveDescendant } from '@fluentui/react-aria';
3
3
  import { mergeCallbacks, useControllableState, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';
4
4
  import { getDropdownActionFromKey } from './dropdownKeyActions';
5
- import { TextCursorPositionPlugin } from '../../plugins/TextCursorPositionPlugin';
5
+ import { CursorPositionPlugin } from '../../plugins/CursorPositionPlugin';
6
6
  import { useOptionCollection } from './useOptionCollection';
7
7
  import { useSelection } from './useSelection';
8
- import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp } from '@fluentui/keyboard-keys';
8
+ import { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';
9
9
  import { useComboboxPositioning } from './useComboboxPositioning';
10
10
  import { useTriggerKeydown } from './useTriggerKeyDown';
11
11
  import { PromptListbox } from '../PromptListbox';
@@ -35,7 +35,7 @@ export function usePromptListboxFunctionality(params) {
35
35
  const {
36
36
  getOptionById
37
37
  } = optionCollection;
38
- const [isInLastPosition, setIsInLastPosition] = React.useState(true);
38
+ const [cursorPosition, setCursorPosition] = React.useState('end');
39
39
  const [isInSelectionMode, setIsInSelectionMode] = React.useState(false);
40
40
  const [open, setOpen] = useControllableState({
41
41
  state: params.open,
@@ -62,8 +62,8 @@ export function usePromptListboxFunctionality(params) {
62
62
  });
63
63
  }
64
64
  };
65
- const cursorPositionPlugin = /*#__PURE__*/React.createElement(TextCursorPositionPlugin, {
66
- setIsInLastPosition: setIsInLastPosition
65
+ const cursorPositionPlugin = /*#__PURE__*/React.createElement(CursorPositionPlugin, {
66
+ setCursorPosition: setCursorPosition
67
67
  });
68
68
  const onListboxBlur = React.useCallback(() => {
69
69
  setIsInSelectionMode(false);
@@ -76,7 +76,7 @@ export function usePromptListboxFunctionality(params) {
76
76
  getOptionById,
77
77
  onBlur: onListboxBlur,
78
78
  selectOption,
79
- isInLastPosition,
79
+ cursorPosition,
80
80
  open,
81
81
  multiselect: false
82
82
  });
@@ -92,9 +92,9 @@ export function usePromptListboxFunctionality(params) {
92
92
  const action = getDropdownActionFromKey(event, {
93
93
  open,
94
94
  multiselect: false,
95
- isInLastPosition
95
+ cursorPosition
96
96
  });
97
- if (event.key === ArrowLeft || event.key === ArrowRight || !isInLastPosition && (event.key === ArrowDown || event.key === ArrowUp) || action === 'Type' && isInLastPosition || action === 'Type') {
97
+ if (event.key === ArrowLeft || event.key === ArrowRight || action === 'Type') {
98
98
  activeDescendantController.blur();
99
99
  setHideActiveDescendant(true);
100
100
  setIsInSelectionMode(false);
@@ -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, 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 activeDescendantController.blur();\n setHideActiveDescendant(true);\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","blur","setHideActiveDescendant","onFocus","target","currentTarget","cursorPositionPlugin","onListboxBlur","useCallback","onKeyDown","multiselect","hideActiveDescendant","onInputTriggerKeyDown","action","key","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 { CursorPositionPlugin } from '../../plugins/CursorPositionPlugin';\nimport { useOptionCollection } from './useOptionCollection';\nimport { useSelection } from './useSelection';\nimport { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';\nimport { useComboboxPositioning } from './useComboboxPositioning';\nimport { useTriggerKeydown } from './useTriggerKeyDown';\nimport { PromptListbox } from '../PromptListbox';\nimport { promptOptionClassNames } from '../PromptOption';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\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 [cursorPosition, setCursorPosition] = React.useState<CursorPosition>('end');\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 activeDescendantController.blur();\n setHideActiveDescendant(true);\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 = <CursorPositionPlugin setCursorPosition={setCursorPosition} />;\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 cursorPosition,\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, cursorPosition });\n if (event.key === ArrowLeft || event.key === ArrowRight || action === 'Type') {\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","CursorPositionPlugin","useOptionCollection","useSelection","ArrowLeft","ArrowRight","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","cursorPosition","setCursorPosition","useState","isInSelectionMode","setIsInSelectionMode","open","setOpen","state","defaultState","defaultOpen","initialState","onBlur","event","type","blur","setHideActiveDescendant","onFocus","target","currentTarget","cursorPositionPlugin","onListboxBlur","useCallback","onKeyDown","multiselect","hideActiveDescendant","onInputTriggerKeyDown","action","key","useEffect","current","removeAttribute","comboboxPopupRef","comboboxTargetRef","listboxMergedRef","ref","listbox","useMemo","promptListbox","triggerProps","containerRef"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -13,7 +13,7 @@ export function useTriggerKeydown(options) {
13
13
  selectOption,
14
14
  multiselect,
15
15
  open,
16
- isInLastPosition,
16
+ cursorPosition,
17
17
  onBlur
18
18
  } = options;
19
19
  const getActiveOption = React.useCallback(() => {
@@ -59,7 +59,7 @@ export function useTriggerKeydown(options) {
59
59
  const action = getDropdownActionFromKey(e, {
60
60
  open,
61
61
  multiselect,
62
- isInLastPosition
62
+ cursorPosition
63
63
  });
64
64
  const activeOption = getActiveOption();
65
65
  const firstOption = activeDescendantController.first({
@@ -1 +1 @@
1
- {"version":3,"sources":["useTriggerKeyDown.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case and added the bluring\n * functionality.\n */\n\nimport * as React from 'react';\nimport { useSetKeyboardNavigation } from '@fluentui/react-tabster';\nimport { useEventCallback } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport type { ActiveDescendantImperativeRef } from '@fluentui/react-aria';\nimport type { OptionCollectionState, OptionValue } from './OptionCollection.types';\nimport type { SelectionProps, SelectionState } from './Selection.types';\n\nexport function useTriggerKeydown(\n options: {\n activeDescendantController: ActiveDescendantImperativeRef;\n isInLastPosition: boolean;\n open: boolean;\n onBlur: () => void;\n } & OptionCollectionState &\n Pick<SelectionProps, 'multiselect'> &\n Pick<SelectionState, 'selectOption'>,\n) {\n const { activeDescendantController, getOptionById, selectOption, multiselect, open, isInLastPosition, onBlur } =\n options;\n\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : undefined;\n }, [activeDescendantController, getOptionById]);\n\n const first = () => {\n activeDescendantController.first();\n };\n\n const last = () => {\n activeDescendantController.last();\n };\n\n const blur = () => {\n activeDescendantController.blur();\n onBlur();\n };\n\n const next = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.next();\n } else {\n activeDescendantController.first();\n }\n };\n\n const previous = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.prev();\n } else {\n activeDescendantController.first();\n }\n };\n\n const pageUp = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.prev();\n }\n };\n\n const pageDown = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.next();\n }\n };\n\n const setKeyboardNavigation = useSetKeyboardNavigation();\n return useEventCallback((e: React.KeyboardEvent<HTMLSpanElement>) => {\n const action = getDropdownActionFromKey(e, { open, multiselect, isInLastPosition });\n const activeOption = getActiveOption();\n const firstOption = activeDescendantController.first({ passive: true });\n\n switch (action) {\n case 'Last':\n case 'First':\n case 'PageDown':\n case 'PageUp':\n case 'CloseSelect':\n case 'Select':\n e.preventDefault();\n break;\n case 'Previous':\n // when active option is the first option and the action was \"Previous\",\n // this means we were in the first option and we are \"leaving\" the listbox\n if (activeOption?.id === firstOption) {\n blur();\n e.preventDefault();\n } else if (activeOption) {\n e.preventDefault();\n }\n break;\n case 'Next':\n e.preventDefault();\n break;\n }\n\n setKeyboardNavigation(true);\n\n switch (action) {\n case 'First':\n first();\n break;\n case 'Last':\n last();\n break;\n case 'Next':\n next(activeOption);\n break;\n case 'Previous':\n if (activeOption && activeOption.id !== firstOption) {\n previous(activeOption);\n } else {\n blur();\n }\n break;\n case 'PageDown':\n pageDown();\n break;\n case 'PageUp':\n pageUp();\n break;\n case 'CloseSelect':\n if (!multiselect && !activeOption?.disabled) {\n blur();\n }\n // fallthrough\n case 'Select':\n activeOption && selectOption(e, activeOption);\n break;\n case 'Tab':\n !multiselect && activeOption && selectOption(e, activeOption);\n break;\n }\n });\n}\n"],"names":["React","useSetKeyboardNavigation","useEventCallback","getDropdownActionFromKey","useTriggerKeydown","options","activeDescendantController","getOptionById","selectOption","multiselect","open","isInLastPosition","onBlur","getActiveOption","useCallback","activeOptionId","active","undefined","first","last","blur","next","activeOption","previous","prev","pageUp","i","pageDown","setKeyboardNavigation","e","action","firstOption","passive","preventDefault","id","disabled"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;CAIC,GAED,YAAYA,WAAW,QAAQ;AAC/B,SAASC,wBAAwB,QAAQ,0BAA0B;AACnE,SAASC,gBAAgB,QAAQ,4BAA4B;AAC7D,SAASC,wBAAwB,QAAQ,uBAAuB;AAKhE,OAAO,SAASC,kBACdC,OAOsC;IAEtC,MAAM,EAAEC,0BAA0B,EAAEC,aAAa,EAAEC,YAAY,EAAEC,WAAW,EAAEC,IAAI,EAAEC,gBAAgB,EAAEC,MAAM,EAAE,GAC5GP;IAEF,MAAMQ,kBAAkBb,MAAMc,WAAW,CAAC;QACxC,MAAMC,iBAAiBT,2BAA2BU,MAAM;QACxD,OAAOD,iBAAiBR,cAAcQ,kBAAkBE;IAC1D,GAAG;QAACX;QAA4BC;KAAc;IAE9C,MAAMW,QAAQ;QACZZ,2BAA2BY,KAAK;IAClC;IAEA,MAAMC,OAAO;QACXb,2BAA2Ba,IAAI;IACjC;IAEA,MAAMC,OAAO;QACXd,2BAA2Bc,IAAI;QAC/BR;IACF;IAEA,MAAMS,OAAO,CAACC;QACZ,IAAIA,cAAc;YAChBhB,2BAA2Be,IAAI;QACjC,OAAO;YACLf,2BAA2BY,KAAK;QAClC;IACF;IAEA,MAAMK,WAAW,CAACD;QAChB,IAAIA,cAAc;YAChBhB,2BAA2BkB,IAAI;QACjC,OAAO;YACLlB,2BAA2BY,KAAK;QAClC;IACF;IAEA,MAAMO,SAAS;QACb,IAAK,IAAIC,IAAI,GAAGA,IAAI,IAAIA,IAAK;YAC3BpB,2BAA2BkB,IAAI;QACjC;IACF;IAEA,MAAMG,WAAW;QACf,IAAK,IAAID,IAAI,GAAGA,IAAI,IAAIA,IAAK;YAC3BpB,2BAA2Be,IAAI;QACjC;IACF;IAEA,MAAMO,wBAAwB3B;IAC9B,OAAOC,iBAAiB,CAAC2B;QACvB,MAAMC,SAAS3B,yBAAyB0B,GAAG;YAAEnB;YAAMD;YAAaE;QAAiB;QACjF,MAAMW,eAAeT;QACrB,MAAMkB,cAAczB,2BAA2BY,KAAK,CAAC;YAAEc,SAAS;QAAK;QAErE,OAAQF;YACN,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;gBACHD,EAAEI,cAAc;gBAChB;YACF,KAAK;gBACH,wEAAwE;gBACxE,0EAA0E;gBAC1E,IAAIX,CAAAA,yBAAAA,mCAAAA,aAAcY,EAAE,MAAKH,aAAa;oBACpCX;oBACAS,EAAEI,cAAc;gBAClB,OAAO,IAAIX,cAAc;oBACvBO,EAAEI,cAAc;gBAClB;gBACA;YACF,KAAK;gBACHJ,EAAEI,cAAc;gBAChB;QACJ;QAEAL,sBAAsB;QAEtB,OAAQE;YACN,KAAK;gBACHZ;gBACA;YACF,KAAK;gBACHC;gBACA;YACF,KAAK;gBACHE,KAAKC;gBACL;YACF,KAAK;gBACH,IAAIA,gBAAgBA,aAAaY,EAAE,KAAKH,aAAa;oBACnDR,SAASD;gBACX,OAAO;oBACLF;gBACF;gBACA;YACF,KAAK;gBACHO;gBACA;YACF,KAAK;gBACHF;gBACA;YACF,KAAK;gBACH,IAAI,CAAChB,eAAe,EAACa,yBAAAA,mCAAAA,aAAca,QAAQ,GAAE;oBAC3Cf;gBACF;YACF,cAAc;YACd,KAAK;gBACHE,gBAAgBd,aAAaqB,GAAGP;gBAChC;YACF,KAAK;gBACH,CAACb,eAAea,gBAAgBd,aAAaqB,GAAGP;gBAChD;QACJ;IACF;AACF"}
1
+ {"version":3,"sources":["useTriggerKeyDown.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case and added the bluring\n * functionality.\n */\n\nimport * as React from 'react';\nimport { useSetKeyboardNavigation } from '@fluentui/react-tabster';\nimport { useEventCallback } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport type { ActiveDescendantImperativeRef } from '@fluentui/react-aria';\nimport type { OptionCollectionState, OptionValue } from './OptionCollection.types';\nimport type { SelectionProps, SelectionState } from './Selection.types';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\n\nexport function useTriggerKeydown(\n options: {\n activeDescendantController: ActiveDescendantImperativeRef;\n cursorPosition: CursorPosition;\n open: boolean;\n onBlur: () => void;\n } & OptionCollectionState &\n Pick<SelectionProps, 'multiselect'> &\n Pick<SelectionState, 'selectOption'>,\n) {\n const { activeDescendantController, getOptionById, selectOption, multiselect, open, cursorPosition, onBlur } =\n options;\n\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : undefined;\n }, [activeDescendantController, getOptionById]);\n\n const first = () => {\n activeDescendantController.first();\n };\n\n const last = () => {\n activeDescendantController.last();\n };\n\n const blur = () => {\n activeDescendantController.blur();\n onBlur();\n };\n\n const next = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.next();\n } else {\n activeDescendantController.first();\n }\n };\n\n const previous = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.prev();\n } else {\n activeDescendantController.first();\n }\n };\n\n const pageUp = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.prev();\n }\n };\n\n const pageDown = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.next();\n }\n };\n\n const setKeyboardNavigation = useSetKeyboardNavigation();\n return useEventCallback((e: React.KeyboardEvent<HTMLSpanElement>) => {\n const action = getDropdownActionFromKey(e, { open, multiselect, cursorPosition });\n const activeOption = getActiveOption();\n const firstOption = activeDescendantController.first({ passive: true });\n\n switch (action) {\n case 'Last':\n case 'First':\n case 'PageDown':\n case 'PageUp':\n case 'CloseSelect':\n case 'Select':\n e.preventDefault();\n break;\n case 'Previous':\n // when active option is the first option and the action was \"Previous\",\n // this means we were in the first option and we are \"leaving\" the listbox\n if (activeOption?.id === firstOption) {\n blur();\n e.preventDefault();\n } else if (activeOption) {\n e.preventDefault();\n }\n break;\n case 'Next':\n e.preventDefault();\n break;\n }\n\n setKeyboardNavigation(true);\n\n switch (action) {\n case 'First':\n first();\n break;\n case 'Last':\n last();\n break;\n case 'Next':\n next(activeOption);\n break;\n case 'Previous':\n if (activeOption && activeOption.id !== firstOption) {\n previous(activeOption);\n } else {\n blur();\n }\n break;\n case 'PageDown':\n pageDown();\n break;\n case 'PageUp':\n pageUp();\n break;\n case 'CloseSelect':\n if (!multiselect && !activeOption?.disabled) {\n blur();\n }\n // fallthrough\n case 'Select':\n activeOption && selectOption(e, activeOption);\n break;\n case 'Tab':\n !multiselect && activeOption && selectOption(e, activeOption);\n break;\n }\n });\n}\n"],"names":["React","useSetKeyboardNavigation","useEventCallback","getDropdownActionFromKey","useTriggerKeydown","options","activeDescendantController","getOptionById","selectOption","multiselect","open","cursorPosition","onBlur","getActiveOption","useCallback","activeOptionId","active","undefined","first","last","blur","next","activeOption","previous","prev","pageUp","i","pageDown","setKeyboardNavigation","e","action","firstOption","passive","preventDefault","id","disabled"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;CAIC,GAED,YAAYA,WAAW,QAAQ;AAC/B,SAASC,wBAAwB,QAAQ,0BAA0B;AACnE,SAASC,gBAAgB,QAAQ,4BAA4B;AAC7D,SAASC,wBAAwB,QAAQ,uBAAuB;AAMhE,OAAO,SAASC,kBACdC,OAOsC;IAEtC,MAAM,EAAEC,0BAA0B,EAAEC,aAAa,EAAEC,YAAY,EAAEC,WAAW,EAAEC,IAAI,EAAEC,cAAc,EAAEC,MAAM,EAAE,GAC1GP;IAEF,MAAMQ,kBAAkBb,MAAMc,WAAW,CAAC;QACxC,MAAMC,iBAAiBT,2BAA2BU,MAAM;QACxD,OAAOD,iBAAiBR,cAAcQ,kBAAkBE;IAC1D,GAAG;QAACX;QAA4BC;KAAc;IAE9C,MAAMW,QAAQ;QACZZ,2BAA2BY,KAAK;IAClC;IAEA,MAAMC,OAAO;QACXb,2BAA2Ba,IAAI;IACjC;IAEA,MAAMC,OAAO;QACXd,2BAA2Bc,IAAI;QAC/BR;IACF;IAEA,MAAMS,OAAO,CAACC;QACZ,IAAIA,cAAc;YAChBhB,2BAA2Be,IAAI;QACjC,OAAO;YACLf,2BAA2BY,KAAK;QAClC;IACF;IAEA,MAAMK,WAAW,CAACD;QAChB,IAAIA,cAAc;YAChBhB,2BAA2BkB,IAAI;QACjC,OAAO;YACLlB,2BAA2BY,KAAK;QAClC;IACF;IAEA,MAAMO,SAAS;QACb,IAAK,IAAIC,IAAI,GAAGA,IAAI,IAAIA,IAAK;YAC3BpB,2BAA2BkB,IAAI;QACjC;IACF;IAEA,MAAMG,WAAW;QACf,IAAK,IAAID,IAAI,GAAGA,IAAI,IAAIA,IAAK;YAC3BpB,2BAA2Be,IAAI;QACjC;IACF;IAEA,MAAMO,wBAAwB3B;IAC9B,OAAOC,iBAAiB,CAAC2B;QACvB,MAAMC,SAAS3B,yBAAyB0B,GAAG;YAAEnB;YAAMD;YAAaE;QAAe;QAC/E,MAAMW,eAAeT;QACrB,MAAMkB,cAAczB,2BAA2BY,KAAK,CAAC;YAAEc,SAAS;QAAK;QAErE,OAAQF;YACN,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;YACL,KAAK;gBACHD,EAAEI,cAAc;gBAChB;YACF,KAAK;gBACH,wEAAwE;gBACxE,0EAA0E;gBAC1E,IAAIX,CAAAA,yBAAAA,mCAAAA,aAAcY,EAAE,MAAKH,aAAa;oBACpCX;oBACAS,EAAEI,cAAc;gBAClB,OAAO,IAAIX,cAAc;oBACvBO,EAAEI,cAAc;gBAClB;gBACA;YACF,KAAK;gBACHJ,EAAEI,cAAc;gBAChB;QACJ;QAEAL,sBAAsB;QAEtB,OAAQE;YACN,KAAK;gBACHZ;gBACA;YACF,KAAK;gBACHC;gBACA;YACF,KAAK;gBACHE,KAAKC;gBACL;YACF,KAAK;gBACH,IAAIA,gBAAgBA,aAAaY,EAAE,KAAKH,aAAa;oBACnDR,SAASD;gBACX,OAAO;oBACLF;gBACF;gBACA;YACF,KAAK;gBACHO;gBACA;YACF,KAAK;gBACHF;gBACA;YACF,KAAK;gBACH,IAAI,CAAChB,eAAe,EAACa,yBAAAA,mCAAAA,aAAca,QAAQ,GAAE;oBAC3Cf;gBACF;YACF,cAAc;YACd,KAAK;gBACHE,gBAAgBd,aAAaqB,GAAGP;gBAChC;YACF,KAAK;gBACH,CAACb,eAAea,gBAAgBd,aAAaqB,GAAGP;gBAChD;QACJ;IACF;AACF"}
package/lib/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export { PromptListbox, promptListboxClassNames, renderPromptListbox_unstable, usePromptListboxStyles_unstable, usePromptListbox_unstable } from './PromptListbox';
2
2
  export { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionality';
3
- export { TextCursorPositionPlugin } from './plugins/TextCursorPositionPlugin';
4
3
  export { PromptOption, promptOptionClassNames, renderPromptOption_unstable, usePromptOptionStyles_unstable, usePromptOption_unstable } from './PromptOption';
5
4
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export type { PromptListboxProps, PromptListboxSlots, PromptListboxState } from './PromptListbox';\nexport {\n PromptListbox,\n promptListboxClassNames,\n renderPromptListbox_unstable,\n usePromptListboxStyles_unstable,\n usePromptListbox_unstable,\n} from './PromptListbox';\n\nexport { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionality';\nexport type {\n OnOpenChangeData,\n ProcessedPromptListboxProps,\n UsePromptListboxFunctionality,\n UsePromptListboxFunctionalityParams,\n} from './components/utils/PromptListboxFunctionality.types';\n\nexport type { TextCursorPositionPluginProps } from './plugins/TextCursorPositionPlugin';\nexport { TextCursorPositionPlugin } from './plugins/TextCursorPositionPlugin';\n\nexport type { PromptOptionProps, PromptOptionSlots, PromptOptionState } from './PromptOption';\nexport {\n PromptOption,\n promptOptionClassNames,\n renderPromptOption_unstable,\n usePromptOptionStyles_unstable,\n usePromptOption_unstable,\n} from './PromptOption';\n"],"names":["PromptListbox","promptListboxClassNames","renderPromptListbox_unstable","usePromptListboxStyles_unstable","usePromptListbox_unstable","usePromptListboxFunctionality","TextCursorPositionPlugin","PromptOption","promptOptionClassNames","renderPromptOption_unstable","usePromptOptionStyles_unstable","usePromptOption_unstable"],"rangeMappings":";;;","mappings":"AACA,SACEA,aAAa,EACbC,uBAAuB,EACvBC,4BAA4B,EAC5BC,+BAA+B,EAC/BC,yBAAyB,QACpB,kBAAkB;AAEzB,SAASC,6BAA6B,QAAQ,mDAAmD;AASjG,SAASC,wBAAwB,QAAQ,qCAAqC;AAG9E,SACEC,YAAY,EACZC,sBAAsB,EACtBC,2BAA2B,EAC3BC,8BAA8B,EAC9BC,wBAAwB,QACnB,iBAAiB"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export type { PromptListboxProps, PromptListboxSlots, PromptListboxState } from './PromptListbox';\nexport {\n PromptListbox,\n promptListboxClassNames,\n renderPromptListbox_unstable,\n usePromptListboxStyles_unstable,\n usePromptListbox_unstable,\n} from './PromptListbox';\n\nexport { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionality';\nexport type {\n OnOpenChangeData,\n ProcessedPromptListboxProps,\n UsePromptListboxFunctionality,\n UsePromptListboxFunctionalityParams,\n} from './components/utils/PromptListboxFunctionality.types';\n\nexport type { PromptOptionProps, PromptOptionSlots, PromptOptionState } from './PromptOption';\nexport {\n PromptOption,\n promptOptionClassNames,\n renderPromptOption_unstable,\n usePromptOptionStyles_unstable,\n usePromptOption_unstable,\n} from './PromptOption';\n"],"names":["PromptListbox","promptListboxClassNames","renderPromptListbox_unstable","usePromptListboxStyles_unstable","usePromptListbox_unstable","usePromptListboxFunctionality","PromptOption","promptOptionClassNames","renderPromptOption_unstable","usePromptOptionStyles_unstable","usePromptOption_unstable"],"rangeMappings":";;","mappings":"AACA,SACEA,aAAa,EACbC,uBAAuB,EACvBC,4BAA4B,EAC5BC,+BAA+B,EAC/BC,yBAAyB,QACpB,kBAAkB;AAEzB,SAASC,6BAA6B,QAAQ,mDAAmD;AASjG,SACEC,YAAY,EACZC,sBAAsB,EACtBC,2BAA2B,EAC3BC,8BAA8B,EAC9BC,wBAAwB,QACnB,iBAAiB"}
@@ -0,0 +1,42 @@
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 = ({
5
+ setCursorPosition
6
+ }) => {
7
+ const [editor] = useLexicalComposerContext();
8
+ React.useEffect(() => {
9
+ const $selectionChangeHandler = () => {
10
+ const selection = $getSelection();
11
+ // If selection is null, the cursor is not active in the editor and we should just noop
12
+ if (selection === null || !$isRangeSelection(selection) || !selection.isCollapsed()) {
13
+ setCursorPosition('between-text');
14
+ return false;
15
+ }
16
+ // Should only be one node in the selection because the selection is collapsed
17
+ const selectedNode = selection.getNodes().at(0);
18
+ // If there's no selected node, focus isn't in the editor
19
+ if (!selectedNode) {
20
+ return false;
21
+ }
22
+ // If there are no leaf nodes, the paragraph node will be selected
23
+ if ($isElementNode(selectedNode)) {
24
+ setCursorPosition('end');
25
+ return false;
26
+ }
27
+ // if the selection node is a sentinel and it matches the sentinel at the end
28
+ if ($isSentinelNode(selectedNode) && !selectedNode.getNextSibling()) {
29
+ setCursorPosition('end');
30
+ return false;
31
+ } else if ($isSentinelNode(selectedNode.getNextSibling()) && selection.focus.offset === selectedNode.getTextContentSize()) {
32
+ setCursorPosition('end');
33
+ return false;
34
+ }
35
+ setCursorPosition('between-text');
36
+ return false;
37
+ };
38
+ return editor.registerCommand(SELECTION_CHANGE_COMMAND, $selectionChangeHandler, COMMAND_PRIORITY_HIGH);
39
+ }, [editor, setCursorPosition]);
40
+ return null;
41
+ };
42
+ //# sourceMappingURL=CursorPositionPlugin.js.map
@@ -0,0 +1 @@
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 = 'end' | 'between-text';\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('end');\n return false;\n }\n\n // if the selection node is a sentinel and it matches the sentinel at the end\n 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 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","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;YAEA,6EAA6E;YAC7E,IAAIT,gBAAgBe,iBAAiB,CAACA,aAAaG,cAAc,IAAI;gBACnET,kBAAkB;gBAClB,OAAO;YACT,OAIK,IACHT,gBAAgBe,aAAaG,cAAc,OAC3CL,UAAUM,KAAK,CAACC,MAAM,KAAKL,aAAaM,kBAAkB,IAC1D;gBACAZ,kBAAkB;gBAClB,OAAO;YACT;YAEAA,kBAAkB;YAClB,OAAO;QACT;QAEA,OAAOC,OAAOY,eAAe,CAACrB,0BAA0BW,yBAAyBN;IACnF,GAAG;QAACI;QAAQD;KAAkB;IAE9B,OAAO;AACT,EAAE"}
@@ -14,7 +14,7 @@ Object.defineProperty(exports, "getDropdownActionFromKey", {
14
14
  const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
15
15
  const _keyboardkeys = /*#__PURE__*/ _interop_require_wildcard._(require("@fluentui/keyboard-keys"));
16
16
  function getDropdownActionFromKey(e, options) {
17
- const { isInLastPosition } = options;
17
+ const { cursorPosition } = options;
18
18
  const code = e.key;
19
19
  const { altKey, ctrlKey, key, metaKey } = e;
20
20
  // typing action occurs whether open or closed
@@ -27,16 +27,16 @@ function getDropdownActionFromKey(e, options) {
27
27
  }
28
28
  // navigation interactions
29
29
  if (code === _keyboardkeys.ArrowDown) {
30
- return isInLastPosition ? 'Next' : 'Type';
30
+ return cursorPosition === 'end' ? 'Next' : 'Type';
31
31
  }
32
32
  if (code === _keyboardkeys.ArrowUp) {
33
- return isInLastPosition ? 'Previous' : 'Type';
33
+ return cursorPosition === 'end' ? 'Previous' : 'Type';
34
34
  }
35
35
  if (code === _keyboardkeys.Home) {
36
- return 'First';
36
+ return cursorPosition === 'end' ? 'First' : 'Type';
37
37
  }
38
38
  if (code === _keyboardkeys.End) {
39
- return 'Last';
39
+ return cursorPosition === 'end' ? 'Last' : 'Type';
40
40
  }
41
41
  if (code === _keyboardkeys.PageUp) {
42
42
  return 'PageUp';
@@ -1 +1 @@
1
- {"version":3,"sources":["dropdownKeyActions.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case.\n */\n\nimport * as keys from '@fluentui/keyboard-keys';\nimport type * as React from 'react';\n\n/**\n * enum of actions available in any type of managed dropdown control\n * e.g. combobox, select, datepicker, menu\n */\nexport type DropdownActions =\n | 'CloseSelect'\n | 'First'\n | 'Last'\n | 'Next'\n | 'None'\n | 'PageDown'\n | 'PageUp'\n | 'Previous'\n | 'Select'\n | 'Tab'\n | 'Type';\n\nexport interface DropdownActionOptions {\n open?: boolean;\n multiselect?: boolean;\n isInLastPosition: boolean;\n}\n\n/**\n * Converts a keyboard interaction into a defined action\n */\nexport function getDropdownActionFromKey(\n e: KeyboardEvent | React.KeyboardEvent,\n options: DropdownActionOptions,\n): DropdownActions {\n const { isInLastPosition } = options;\n const code = e.key;\n const { altKey, ctrlKey, key, metaKey } = e;\n\n // typing action occurs whether open or closed\n if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {\n return 'Type';\n }\n\n // select or close actions\n if ((code === keys.ArrowUp && altKey) || code === keys.Enter) {\n return 'CloseSelect';\n }\n\n // navigation interactions\n if (code === keys.ArrowDown) {\n return isInLastPosition ? 'Next' : 'Type';\n }\n if (code === keys.ArrowUp) {\n return isInLastPosition ? 'Previous' : 'Type';\n }\n if (code === keys.Home) {\n return 'First';\n }\n if (code === keys.End) {\n return 'Last';\n }\n if (code === keys.PageUp) {\n return 'PageUp';\n }\n if (code === keys.PageDown) {\n return 'PageDown';\n }\n if (code === keys.Tab) {\n return 'Tab';\n }\n\n // if nothing matched, return none\n return 'None';\n}\n"],"names":["isInLastPosition","keys","options","ctrlKey","key","length","altKey","e","code","ArrowDown","Space","metaKey","ArrowUp","Enter","Home","End","PageUp","PageDown"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;CAGC;;;;+BAmCSA;;;eAAAA;;;;wEAjCEC;AAiCV,SAAQD,yBAAqBE,CAAAA,EAAAA,OAAAA;UAC7B,EACAF,gBAAgBG,KAEhBD;UACIE,OAAIC,EAAAA,GAAM;UACZ,EACFC,MAAA,EAEAH,OAAA,EACAC,GAAA,SACE,KACFG;kDAE0B;QAC1BH,IAAII,MAAAA,KAASP,KAAKQ,SAAWR,cAAAS,KAAA,IAAA,CAAAJ,UAAA,CAAAH,WAAA,CAAAQ,SAAA;eAC3B;;8BAEgBC;iBACTZ,cAAAA,OAAAA,IAAAA,UAAmBQ,SAAaP,cAAAY,KAAA,EAAA;QACzC,OAAA;;8BAES;QACTL,SAAAP,cAAAQ,SAAA,EAAA;QACA,OAAID,mBAAmB,SAAA;;QAEvBA,SAAAP,cAAAW,OAAA,EAAA;QACA,OAAIJ,mBAAsB,aAAA;;QAE1BA,SAAAP,cAAAa,IAAA,EAAA;QACA,OAAIN;;QAEJA,SAAAP,cAAAc,GAAA,EAAA;QACA,OAAIP;;QAEJA,SAAAP,cAAAe,MAAA,EAAA;QAEA,OAAA;;IAEF,IAAAR,SAAAP,cAAAgB,QAAA,EAAA"}
1
+ {"version":3,"sources":["dropdownKeyActions.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case.\n */\n\nimport * as keys from '@fluentui/keyboard-keys';\nimport type * as React from 'react';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\n\n/**\n * enum of actions available in any type of managed dropdown control\n * e.g. combobox, select, datepicker, menu\n */\nexport type DropdownActions =\n | 'CloseSelect'\n | 'First'\n | 'Last'\n | 'Next'\n | 'None'\n | 'PageDown'\n | 'PageUp'\n | 'Previous'\n | 'Select'\n | 'Tab'\n | 'Type';\n\nexport interface DropdownActionOptions {\n open?: boolean;\n multiselect?: boolean;\n cursorPosition: CursorPosition;\n}\n\n/**\n * Converts a keyboard interaction into a defined action\n */\nexport function getDropdownActionFromKey(\n e: KeyboardEvent | React.KeyboardEvent,\n options: DropdownActionOptions,\n): DropdownActions {\n const { cursorPosition } = options;\n const code = e.key;\n const { altKey, ctrlKey, key, metaKey } = e;\n\n // typing action occurs whether open or closed\n if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {\n return 'Type';\n }\n\n // select or close actions\n if ((code === keys.ArrowUp && altKey) || code === keys.Enter) {\n return 'CloseSelect';\n }\n\n // navigation interactions\n if (code === keys.ArrowDown) {\n return cursorPosition === 'end' ? 'Next' : 'Type';\n }\n if (code === keys.ArrowUp) {\n return cursorPosition === 'end' ? 'Previous' : 'Type';\n }\n if (code === keys.Home) {\n return cursorPosition === 'end' ? 'First' : 'Type';\n }\n if (code === keys.End) {\n return cursorPosition === 'end' ? 'Last' : 'Type';\n }\n if (code === keys.PageUp) {\n return 'PageUp';\n }\n if (code === keys.PageDown) {\n return 'PageDown';\n }\n if (code === keys.Tab) {\n return 'Tab';\n }\n\n // if nothing matched, return none\n return 'None';\n}\n"],"names":["cursorPosition","keys","options","key","length","altKey","ctrlKey","e","code","ArrowDown","Space","metaKey","ArrowUp","Enter","Home","End","PageUp","PageDown"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;CAGC;;;;+BAoCSA;;;eAAAA;;;;wEAlCEC;AAkCV,SAAQD,yBAAmBE,CAAAA,EAAAA,OAAAA;UAC3B,EACAF,cAAc,KAEdE;UACIC,OAAIC,EAAAA,GAAM;UACZ,EACFC,MAAA,EAEAC,OAAA,EACAH,GAAA,SACE,KACFI;kDAE0B;QAC1BJ,IAAIK,MAAAA,KAASP,KAAKQ,SAAWR,cAAAS,KAAA,IAAA,CAAAL,UAAA,CAAAC,WAAA,CAAAK,SAAA;eAC3B;;8BAEgBC;iBACTZ,cAAAA,OAAAA,IAAAA,UAAmBQ,SAAQP,cAAaY,KAAA,EAAA;QACjD,OAAA;;8BAESb;QACTQ,SAAAP,cAAAQ,SAAA,EAAA;QACA,OAAID,mBAAmB,QAAA,SAAA;;QAEvBA,SAAAP,cAAAW,OAAA,EAAA;QACA,OAAIJ,mBAAsB,QAAA,aAAA;;QAE1BA,SAAAP,cAAAa,IAAA,EAAA;QACA,OAAIN,mBAAsB,QAAE,UAAA;;QAE5BA,SAAAP,cAAAc,GAAA,EAAA;QACA,OAAIP,mBAAmB,QAAA,SAAA;;QAEvBA,SAAAP,cAAAe,MAAA,EAAA;QAEA,OAAA;;IAEF,IAAAR,SAAAP,cAAAgB,QAAA,EAAA"}
@@ -13,7 +13,7 @@ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
13
  const _reactaria = require("@fluentui/react-aria");
14
14
  const _reactutilities = require("@fluentui/react-utilities");
15
15
  const _dropdownKeyActions = require("./dropdownKeyActions");
16
- const _TextCursorPositionPlugin = require("../../plugins/TextCursorPositionPlugin");
16
+ const _CursorPositionPlugin = require("../../plugins/CursorPositionPlugin");
17
17
  const _useOptionCollection = require("./useOptionCollection");
18
18
  const _useSelection = require("./useSelection");
19
19
  const _keyboardkeys = require("@fluentui/keyboard-keys");
@@ -32,7 +32,7 @@ function usePromptListboxFunctionality(params) {
32
32
  const { selectOption } = selectionState;
33
33
  const optionCollection = (0, _useOptionCollection.useOptionCollection)();
34
34
  const { getOptionById } = optionCollection;
35
- const [isInLastPosition, setIsInLastPosition] = _react.useState(true);
35
+ const [cursorPosition, setCursorPosition] = _react.useState('end');
36
36
  const [isInSelectionMode, setIsInSelectionMode] = _react.useState(false);
37
37
  const [open, setOpen] = (0, _reactutilities.useControllableState)({
38
38
  state: params.open,
@@ -59,8 +59,8 @@ function usePromptListboxFunctionality(params) {
59
59
  });
60
60
  }
61
61
  };
62
- const cursorPositionPlugin = /*#__PURE__*/ _react.createElement(_TextCursorPositionPlugin.TextCursorPositionPlugin, {
63
- setIsInLastPosition: setIsInLastPosition
62
+ const cursorPositionPlugin = /*#__PURE__*/ _react.createElement(_CursorPositionPlugin.CursorPositionPlugin, {
63
+ setCursorPosition: setCursorPosition
64
64
  });
65
65
  const onListboxBlur = _react.useCallback(()=>{
66
66
  setIsInSelectionMode(false);
@@ -75,7 +75,7 @@ function usePromptListboxFunctionality(params) {
75
75
  getOptionById,
76
76
  onBlur: onListboxBlur,
77
77
  selectOption,
78
- isInLastPosition,
78
+ cursorPosition,
79
79
  open,
80
80
  multiselect: false
81
81
  });
@@ -90,9 +90,9 @@ function usePromptListboxFunctionality(params) {
90
90
  const action = (0, _dropdownKeyActions.getDropdownActionFromKey)(event, {
91
91
  open,
92
92
  multiselect: false,
93
- isInLastPosition
93
+ cursorPosition
94
94
  });
95
- if (event.key === _keyboardkeys.ArrowLeft || event.key === _keyboardkeys.ArrowRight || !isInLastPosition && (event.key === _keyboardkeys.ArrowDown || event.key === _keyboardkeys.ArrowUp) || action === 'Type' && isInLastPosition || action === 'Type') {
95
+ if (event.key === _keyboardkeys.ArrowLeft || event.key === _keyboardkeys.ArrowRight || action === 'Type') {
96
96
  activeDescendantController.blur();
97
97
  setHideActiveDescendant(true);
98
98
  setIsInSelectionMode(false);
@@ -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, 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 activeDescendantController.blur();\n setHideActiveDescendant(true);\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","activeDescendantController","React","useState","setHideActiveDescendant","state","onFocus","target","defaultOpen","currentTarget","onOpenChange","setIsInSelectionMode","type","onKeyDown","onBlur","onListboxBlur","selectOption","useTriggerKeydown","hideActiveDescendant","onInputTriggerKeyDown","multiselect","ArrowDown","action","useEffect","comboboxPopupRef","_triggerRef_current","current","removeAttribute","PromptListbox","listboxMergedRef","ref","listbox","cursorPositionPlugin"],"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 { CursorPositionPlugin } from '../../plugins/CursorPositionPlugin';\nimport { useOptionCollection } from './useOptionCollection';\nimport { useSelection } from './useSelection';\nimport { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';\nimport { useComboboxPositioning } from './useComboboxPositioning';\nimport { useTriggerKeydown } from './useTriggerKeyDown';\nimport { PromptListbox } from '../PromptListbox';\nimport { promptOptionClassNames } from '../PromptOption';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\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 [cursorPosition, setCursorPosition] = React.useState<CursorPosition>('end');\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 activeDescendantController.blur();\n setHideActiveDescendant(true);\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 = <CursorPositionPlugin setCursorPosition={setCursorPosition} />;\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 cursorPosition,\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, cursorPosition });\n if (event.key === ArrowLeft || event.key === ArrowRight || action === 'Type') {\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","cursorPosition","setCursorPosition","useActiveDescendant","isInSelectionMode","setOpen","classList","useControllableState","root","initialState","selectionState","useSelection","event","open","activeDescendantController","React","useState","setHideActiveDescendant","state","onFocus","target","defaultOpen","currentTarget","onOpenChange","setIsInSelectionMode","type","onKeyDown","onBlur","onListboxBlur","selectOption","useTriggerKeydown","hideActiveDescendant","onInputTriggerKeyDown","multiselect","action","useEffect","comboboxPopupRef","_triggerRef_current","current","removeAttribute","PromptListbox","listboxMergedRef","ref","listbox","cursorPositionPlugin"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -18,7 +18,7 @@ const _reacttabster = require("@fluentui/react-tabster");
18
18
  const _reactutilities = require("@fluentui/react-utilities");
19
19
  const _dropdownKeyActions = require("./dropdownKeyActions");
20
20
  function useTriggerKeydown(options) {
21
- const { activeDescendantController, getOptionById, selectOption, multiselect, open, isInLastPosition, onBlur } = options;
21
+ const { activeDescendantController, getOptionById, selectOption, multiselect, open, cursorPosition, onBlur } = options;
22
22
  const getActiveOption = _react.useCallback(()=>{
23
23
  const activeOptionId = activeDescendantController.active();
24
24
  return activeOptionId ? getOptionById(activeOptionId) : undefined;
@@ -65,7 +65,7 @@ function useTriggerKeydown(options) {
65
65
  const action = (0, _dropdownKeyActions.getDropdownActionFromKey)(e, {
66
66
  open,
67
67
  multiselect,
68
- isInLastPosition
68
+ cursorPosition
69
69
  });
70
70
  const activeOption = getActiveOption();
71
71
  const firstOption = activeDescendantController.first({
@@ -1 +1 @@
1
- {"version":3,"sources":["useTriggerKeyDown.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case and added the bluring\n * functionality.\n */\n\nimport * as React from 'react';\nimport { useSetKeyboardNavigation } from '@fluentui/react-tabster';\nimport { useEventCallback } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport type { ActiveDescendantImperativeRef } from '@fluentui/react-aria';\nimport type { OptionCollectionState, OptionValue } from './OptionCollection.types';\nimport type { SelectionProps, SelectionState } from './Selection.types';\n\nexport function useTriggerKeydown(\n options: {\n activeDescendantController: ActiveDescendantImperativeRef;\n isInLastPosition: boolean;\n open: boolean;\n onBlur: () => void;\n } & OptionCollectionState &\n Pick<SelectionProps, 'multiselect'> &\n Pick<SelectionState, 'selectOption'>,\n) {\n const { activeDescendantController, getOptionById, selectOption, multiselect, open, isInLastPosition, onBlur } =\n options;\n\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : undefined;\n }, [activeDescendantController, getOptionById]);\n\n const first = () => {\n activeDescendantController.first();\n };\n\n const last = () => {\n activeDescendantController.last();\n };\n\n const blur = () => {\n activeDescendantController.blur();\n onBlur();\n };\n\n const next = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.next();\n } else {\n activeDescendantController.first();\n }\n };\n\n const previous = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.prev();\n } else {\n activeDescendantController.first();\n }\n };\n\n const pageUp = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.prev();\n }\n };\n\n const pageDown = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.next();\n }\n };\n\n const setKeyboardNavigation = useSetKeyboardNavigation();\n return useEventCallback((e: React.KeyboardEvent<HTMLSpanElement>) => {\n const action = getDropdownActionFromKey(e, { open, multiselect, isInLastPosition });\n const activeOption = getActiveOption();\n const firstOption = activeDescendantController.first({ passive: true });\n\n switch (action) {\n case 'Last':\n case 'First':\n case 'PageDown':\n case 'PageUp':\n case 'CloseSelect':\n case 'Select':\n e.preventDefault();\n break;\n case 'Previous':\n // when active option is the first option and the action was \"Previous\",\n // this means we were in the first option and we are \"leaving\" the listbox\n if (activeOption?.id === firstOption) {\n blur();\n e.preventDefault();\n } else if (activeOption) {\n e.preventDefault();\n }\n break;\n case 'Next':\n e.preventDefault();\n break;\n }\n\n setKeyboardNavigation(true);\n\n switch (action) {\n case 'First':\n first();\n break;\n case 'Last':\n last();\n break;\n case 'Next':\n next(activeOption);\n break;\n case 'Previous':\n if (activeOption && activeOption.id !== firstOption) {\n previous(activeOption);\n } else {\n blur();\n }\n break;\n case 'PageDown':\n pageDown();\n break;\n case 'PageUp':\n pageUp();\n break;\n case 'CloseSelect':\n if (!multiselect && !activeOption?.disabled) {\n blur();\n }\n // fallthrough\n case 'Select':\n activeOption && selectOption(e, activeOption);\n break;\n case 'Tab':\n !multiselect && activeOption && selectOption(e, activeOption);\n break;\n }\n });\n}\n"],"names":["useTriggerKeydown","React","options","activeDescendantController","activeOptionId","multiselect","getOptionById","active","last","undefined","first","onBlur","blur","activeOption","next","previous","prev","pageUp","pageDown","i","setKeyboardNavigation","useEventCallback","e","getDropdownActionFromKey","isInLastPosition","action","getActiveOption","id","firstOption","preventDefault","selectOption"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;CAIC;;;;+BAUeA;;;eAAAA;;;;iEARJC;8BAC6B;gCACR;oCACQ;AAKlC,SAASD,kBACdE,OAOsC;UAEtC,EAGAC,0BAAwBF,eAChBG,cACCA,EACTC,WAAG,MAACF,kBAA4BG,QAAc,KAE9CJ;UACEC,kBAAAA,OAAAA,WAAgC,CAAA;QAClC,MAAAC,iBAAAD,2BAAAI,MAAA;QAEA,OAAMC,iBAAOF,cAAAF,kBAAAK;;;QACXN;KAA+B;UACjCO,QAAA;QAEAP,2BAAaO,KAAA;;UAEXC,OAAAA;QACFR,2BAAAK,IAAA;;UAGEI,OAAIC;mCACFV,IAAAA;;;UAGFW,OAAAD,CAAAA;QACF,IAAAA,cAAA;YAEAV,2BAAkBU,IAAAA;eAChB;uCACEV,KAAAA;;;UAGFY,WAAAF,CAAAA;QACF,IAAAA,cAAA;YAEAV,2BAAea,IAAA;eACb;uCACEb,KAAAA;;;UAIJc,SAAMC;YACJ,IAAKC,IAAIA,GAAIA,IAAGA,IAAIA,IAAIA;uCACtBhB,IAAAA;;;UAIJe,WAAME;QACN,IAAA,IAAOC,IAAAA,GAAAA,IAAAA,IAAiBF,IAACG;uCACRC,IAAAA;;;kCAAiDC,IAAAA,sCAAAA;WAAiBH,IAAAA,gCAAA,EAAAC,CAAAA;cACjFG,SAAMZ,IAAAA,4CAAea,EAAAA,GAAAA;;;;;6BAIdA;4BACAvB,2BAAAO,KAAA,CAAA;qBACL;;eAEAe;;;;;;;gCAOMZ;;;wFAGqB;0FACP;sCAClB,QAAAA,iBAAA,KAAA,IAAA,KAAA,IAAAA,aAAAc,EAAA,MAAAC,aAAA;;sBAEFC,cAAK;2BACDA,cAAc;oCAChB;gBACJ;gBAEAT;iBAEA;gCACO;;;8BAGA;;;;;;;;;;;;oCAYHP,aAAAc,EAAA,KAAAC,aAAA;6BACGf;;;;;;;;;;;;oCAYHA,CAAAA,CAAAA,iBAA6BS,QAAGT,iBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,aAAAA,QAAAA,GAAAA;;;0BAG/BR;;gBAELQ,gBAAAiB,aAAAR,GAAAT;gBACF;YACF,KAAA"}
1
+ {"version":3,"sources":["useTriggerKeyDown.ts"],"sourcesContent":["/**\n * Note, this is mainly brought from Fluent UI, only removed the closing and\n * opening logic since that's not needed for this use case and added the bluring\n * functionality.\n */\n\nimport * as React from 'react';\nimport { useSetKeyboardNavigation } from '@fluentui/react-tabster';\nimport { useEventCallback } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from './dropdownKeyActions';\nimport type { ActiveDescendantImperativeRef } from '@fluentui/react-aria';\nimport type { OptionCollectionState, OptionValue } from './OptionCollection.types';\nimport type { SelectionProps, SelectionState } from './Selection.types';\nimport type { CursorPosition } from '../../plugins/CursorPositionPlugin';\n\nexport function useTriggerKeydown(\n options: {\n activeDescendantController: ActiveDescendantImperativeRef;\n cursorPosition: CursorPosition;\n open: boolean;\n onBlur: () => void;\n } & OptionCollectionState &\n Pick<SelectionProps, 'multiselect'> &\n Pick<SelectionState, 'selectOption'>,\n) {\n const { activeDescendantController, getOptionById, selectOption, multiselect, open, cursorPosition, onBlur } =\n options;\n\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : undefined;\n }, [activeDescendantController, getOptionById]);\n\n const first = () => {\n activeDescendantController.first();\n };\n\n const last = () => {\n activeDescendantController.last();\n };\n\n const blur = () => {\n activeDescendantController.blur();\n onBlur();\n };\n\n const next = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.next();\n } else {\n activeDescendantController.first();\n }\n };\n\n const previous = (activeOption: OptionValue | undefined) => {\n if (activeOption) {\n activeDescendantController.prev();\n } else {\n activeDescendantController.first();\n }\n };\n\n const pageUp = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.prev();\n }\n };\n\n const pageDown = () => {\n for (let i = 0; i < 10; i++) {\n activeDescendantController.next();\n }\n };\n\n const setKeyboardNavigation = useSetKeyboardNavigation();\n return useEventCallback((e: React.KeyboardEvent<HTMLSpanElement>) => {\n const action = getDropdownActionFromKey(e, { open, multiselect, cursorPosition });\n const activeOption = getActiveOption();\n const firstOption = activeDescendantController.first({ passive: true });\n\n switch (action) {\n case 'Last':\n case 'First':\n case 'PageDown':\n case 'PageUp':\n case 'CloseSelect':\n case 'Select':\n e.preventDefault();\n break;\n case 'Previous':\n // when active option is the first option and the action was \"Previous\",\n // this means we were in the first option and we are \"leaving\" the listbox\n if (activeOption?.id === firstOption) {\n blur();\n e.preventDefault();\n } else if (activeOption) {\n e.preventDefault();\n }\n break;\n case 'Next':\n e.preventDefault();\n break;\n }\n\n setKeyboardNavigation(true);\n\n switch (action) {\n case 'First':\n first();\n break;\n case 'Last':\n last();\n break;\n case 'Next':\n next(activeOption);\n break;\n case 'Previous':\n if (activeOption && activeOption.id !== firstOption) {\n previous(activeOption);\n } else {\n blur();\n }\n break;\n case 'PageDown':\n pageDown();\n break;\n case 'PageUp':\n pageUp();\n break;\n case 'CloseSelect':\n if (!multiselect && !activeOption?.disabled) {\n blur();\n }\n // fallthrough\n case 'Select':\n activeOption && selectOption(e, activeOption);\n break;\n case 'Tab':\n !multiselect && activeOption && selectOption(e, activeOption);\n break;\n }\n });\n}\n"],"names":["useTriggerKeydown","React","options","activeDescendantController","activeOptionId","multiselect","getOptionById","active","last","undefined","first","onBlur","blur","activeOption","next","previous","prev","pageUp","pageDown","i","setKeyboardNavigation","useEventCallback","e","getDropdownActionFromKey","cursorPosition","action","getActiveOption","id","firstOption","preventDefault","selectOption"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;CAIC;;;;+BAWeA;;;eAAAA;;;;iEATJC;8BAC6B;gCACR;oCACQ;AAMlC,SAASD,kBACdE,OAOsC;UAEtC,EAGAC,0BAAwBF,eAChBG,cACCA,EACTC,WAAG,MAACF,gBAA4BG,QAAc,KAE9CJ;UACEC,kBAAAA,OAAAA,WAAgC,CAAA;QAClC,MAAAC,iBAAAD,2BAAAI,MAAA;QAEA,OAAMC,iBAAOF,cAAAF,kBAAAK;;;QACXN;KAA+B;UACjCO,QAAA;QAEAP,2BAAaO,KAAA;;UAEXC,OAAAA;QACFR,2BAAAK,IAAA;;UAGEI,OAAIC;mCACFV,IAAAA;;;UAGFW,OAAAD,CAAAA;QACF,IAAAA,cAAA;YAEAV,2BAAkBU,IAAAA;eAChB;uCACEV,KAAAA;;;UAGFY,WAAAF,CAAAA;QACF,IAAAA,cAAA;YAEAV,2BAAea,IAAA;eACb;uCACEb,KAAAA;;;UAIJc,SAAMC;YACJ,IAAKC,IAAIA,GAAIA,IAAGA,IAAIA,IAAIA;uCACtBhB,IAAAA;;;UAIJe,WAAME;QACN,IAAA,IAAOC,IAAAA,GAAAA,IAAAA,IAAiBF,IAACG;uCACRC,IAAAA;;;kCAAiDC,IAAAA,sCAAAA;WAAeH,IAAAA,gCAAA,EAAAC,CAAAA;cAC/EG,SAAMZ,IAAAA,4CAAea,EAAAA,GAAAA;;;;;6BAIdA;4BACAvB,2BAAAO,KAAA,CAAA;qBACL;;eAEAe;;;;;;;gCAOMZ;;;wFAGqB;0FACP;sCAClB,QAAAA,iBAAA,KAAA,IAAA,KAAA,IAAAA,aAAAc,EAAA,MAAAC,aAAA;;sBAEFC,cAAK;2BACDA,cAAc;oCAChB;gBACJ;gBAEAT;iBAEA;gCACO;;;8BAGA;;;;;;;;;;;;oCAYHP,aAAAc,EAAA,KAAAC,aAAA;6BACGf;;;;;;;;;;;;oCAYHA,CAAAA,CAAAA,iBAA6BS,QAAGT,iBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,aAAAA,QAAAA,GAAAA;;;0BAG/BR;;gBAELQ,gBAAAiB,aAAAR,GAAAT;gBACF;YACF,KAAA"}
@@ -15,9 +15,6 @@ _export(exports, {
15
15
  PromptOption: function() {
16
16
  return _PromptOption.PromptOption;
17
17
  },
18
- TextCursorPositionPlugin: function() {
19
- return _TextCursorPositionPlugin.TextCursorPositionPlugin;
20
- },
21
18
  promptListboxClassNames: function() {
22
19
  return _PromptListbox.promptListboxClassNames;
23
20
  },
@@ -48,6 +45,5 @@ _export(exports, {
48
45
  });
49
46
  const _PromptListbox = require("./PromptListbox");
50
47
  const _usePromptListboxFunctionality = require("./components/utils/usePromptListboxFunctionality");
51
- const _TextCursorPositionPlugin = require("./plugins/TextCursorPositionPlugin");
52
48
  const _PromptOption = require("./PromptOption");
53
49
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export type { PromptListboxProps, PromptListboxSlots, PromptListboxState } from './PromptListbox';\nexport {\n PromptListbox,\n promptListboxClassNames,\n renderPromptListbox_unstable,\n usePromptListboxStyles_unstable,\n usePromptListbox_unstable,\n} from './PromptListbox';\n\nexport { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionality';\nexport type {\n OnOpenChangeData,\n ProcessedPromptListboxProps,\n UsePromptListboxFunctionality,\n UsePromptListboxFunctionalityParams,\n} from './components/utils/PromptListboxFunctionality.types';\n\nexport type { TextCursorPositionPluginProps } from './plugins/TextCursorPositionPlugin';\nexport { TextCursorPositionPlugin } from './plugins/TextCursorPositionPlugin';\n\nexport type { PromptOptionProps, PromptOptionSlots, PromptOptionState } from './PromptOption';\nexport {\n PromptOption,\n promptOptionClassNames,\n renderPromptOption_unstable,\n usePromptOptionStyles_unstable,\n usePromptOption_unstable,\n} from './PromptOption';\n"],"names":["PromptListbox","PromptOption","TextCursorPositionPlugin","promptListboxClassNames","promptOptionClassNames","renderPromptListbox_unstable","renderPromptOption_unstable","usePromptListboxFunctionality","usePromptListboxStyles_unstable","usePromptListbox_unstable","usePromptOptionStyles_unstable","usePromptOption_unstable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAEEA,aAAa;eAAbA,4BAAa;;IAoBbC,YAAY;eAAZA,0BAAY;;IAJLC,wBAAwB;eAAxBA,kDAAwB;;IAf/BC,uBAAuB;eAAvBA,sCAAuB;;IAoBvBC,sBAAsB;eAAtBA,oCAAsB;;IAnBtBC,4BAA4B;eAA5BA,2CAA4B;;IAoB5BC,2BAA2B;eAA3BA,yCAA2B;;IAfpBC,6BAA6B;eAA7BA,4DAA6B;;IAJpCC,+BAA+B;eAA/BA,8CAA+B;;IAC/BC,yBAAyB;eAAzBA,wCAAyB;;IAmBzBC,8BAA8B;eAA9BA,4CAA8B;;IAC9BC,wBAAwB;eAAxBA,sCAAwB;;;+BAnBnB;+CAEuC;0CASL;8BASlC"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export type { PromptListboxProps, PromptListboxSlots, PromptListboxState } from './PromptListbox';\nexport {\n PromptListbox,\n promptListboxClassNames,\n renderPromptListbox_unstable,\n usePromptListboxStyles_unstable,\n usePromptListbox_unstable,\n} from './PromptListbox';\n\nexport { usePromptListboxFunctionality } from './components/utils/usePromptListboxFunctionality';\nexport type {\n OnOpenChangeData,\n ProcessedPromptListboxProps,\n UsePromptListboxFunctionality,\n UsePromptListboxFunctionalityParams,\n} from './components/utils/PromptListboxFunctionality.types';\n\nexport type { PromptOptionProps, PromptOptionSlots, PromptOptionState } from './PromptOption';\nexport {\n PromptOption,\n promptOptionClassNames,\n renderPromptOption_unstable,\n usePromptOptionStyles_unstable,\n usePromptOption_unstable,\n} from './PromptOption';\n"],"names":["PromptListbox","PromptOption","promptListboxClassNames","promptOptionClassNames","renderPromptListbox_unstable","renderPromptOption_unstable","usePromptListboxFunctionality","usePromptListboxStyles_unstable","usePromptListbox_unstable","usePromptOptionStyles_unstable","usePromptOption_unstable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IAEEA,aAAa;eAAbA,4BAAa;;IAiBbC,YAAY;eAAZA,0BAAY;;IAhBZC,uBAAuB;eAAvBA,sCAAuB;;IAiBvBC,sBAAsB;eAAtBA,oCAAsB;;IAhBtBC,4BAA4B;eAA5BA,2CAA4B;;IAiB5BC,2BAA2B;eAA3BA,yCAA2B;;IAZpBC,6BAA6B;eAA7BA,4DAA6B;;IAJpCC,+BAA+B;eAA/BA,8CAA+B;;IAC/BC,yBAAyB;eAAzBA,wCAAyB;;IAgBzBC,8BAA8B;eAA9BA,4CAA8B;;IAC9BC,wBAAwB;eAAxBA,sCAAwB;;;+BAhBnB;+CAEuC;8BAevC"}
@@ -0,0 +1,53 @@
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('end');
34
+ return false;
35
+ }
36
+ // if the selection node is a sentinel and it matches the sentinel at the end
37
+ if ((0, _chatinputplugins.$isSentinelNode)(selectedNode) && !selectedNode.getNextSibling()) {
38
+ setCursorPosition('end');
39
+ return false;
40
+ } else if ((0, _chatinputplugins.$isSentinelNode)(selectedNode.getNextSibling()) && selection.focus.offset === selectedNode.getTextContentSize()) {
41
+ setCursorPosition('end');
42
+ return false;
43
+ }
44
+ setCursorPosition('between-text');
45
+ return false;
46
+ };
47
+ return editor.registerCommand(_reacttexteditor.SELECTION_CHANGE_COMMAND, $selectionChangeHandler, _reacttexteditor.COMMAND_PRIORITY_HIGH);
48
+ }, [
49
+ editor,
50
+ setCursorPosition
51
+ ]);
52
+ return null;
53
+ }; //# sourceMappingURL=CursorPositionPlugin.js.map
@@ -0,0 +1 @@
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 = 'end' | 'between-text';\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('end');\n return false;\n }\n\n // if the selection node is a sentinel and it matches the sentinel at the end\n 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 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","editor","$selectionChangeHandler","selection","$isRangeSelection","isCollapsed","selectedNode","getNodes","at","getNextSibling","$isSentinelNode","focus","offset","getTextContentSize","setCursorPosition"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAsBaA;;;eAAAA;;;;kCAtBmB;iCAQzB;iEACgB;AAahB,MAAMA,uBAA2E,CAAC,mBACzE;UAGZ,CAAAC,OAAMC,GAAAA,IAAAA,0CAA0B;oBAC9B,CAAMC;wCACN;kBACAA,YAAIA,IAAAA,8BAAc;mGACE;8BACX,QAAA,CAAAC,IAAAA,kCAAA,EAAAD,cAAA,CAAAA,UAAAE,WAAA,IAAA;kCACT;uBAEA;;0FAEyD;kBACzDC,eAAKA,UAAcC,QAAA,GAAAC,EAAA,CAAA;qEACV;+BACT;uBAEA;;8EAEoB;mDACX,EAAAF,eAAA;kCACT;uBAEA;;yFAEoB;qDACX,EAAAA,iBAAA,CAAAA,aAAAG,cAAA,IAAA;kCAMPC;;uBAIAA,IAAAA,iCAAO,EAAAJ,aAAAG,cAAA,OAAAN,UAAAQ,KAAA,CAAAC,MAAA,KAAAN,aAAAO,kBAAA,IAAA;kCACT;uBAEAC;;8BAEF;mBAEA;QACF;eAAIb,OAAAA,eAAAA,CAAAA,yCAAAA,EAAAA,yBAAAA,sCAAAA;;;QAAQa;KAAAA;WAAkB;GAGhC,gDAAE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-copilot/react-prompt-listbox",
3
- "version": "0.0.0-nightly-20240816-0407-4f31c87a.1",
3
+ "version": "0.0.0-nightly-20240820-0406-cc08f744.1",
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.0.0-nightly-20240816-0407-4f31c87a.1",
16
- "@fluentui-copilot/react-chat-input-plugins": "0.0.0-nightly-20240816-0407-4f31c87a.1",
17
- "@fluentui-copilot/react-editor-input": "0.0.0-nightly-20240816-0407-4f31c87a.1",
18
- "@fluentui-copilot/react-prompt-input": "0.0.0-nightly-20240816-0407-4f31c87a.1",
19
- "@fluentui-copilot/react-provider": "0.0.0-nightly-20240816-0407-4f31c87a.1",
20
- "@fluentui-copilot/react-text-editor": "0.0.0-nightly-20240816-0407-4f31c87a.1",
21
- "@fluentui-copilot/text-editor": "0.0.0-nightly-20240816-0407-4f31c87a.1",
15
+ "@fluentui-copilot/chat-input-plugins": "0.0.0-nightly-20240820-0406-cc08f744.1",
16
+ "@fluentui-copilot/react-chat-input-plugins": "0.0.0-nightly-20240820-0406-cc08f744.1",
17
+ "@fluentui-copilot/react-editor-input": "0.0.0-nightly-20240820-0406-cc08f744.1",
18
+ "@fluentui-copilot/react-prompt-input": "0.0.0-nightly-20240820-0406-cc08f744.1",
19
+ "@fluentui-copilot/react-provider": "0.0.0-nightly-20240820-0406-cc08f744.1",
20
+ "@fluentui-copilot/react-text-editor": "0.0.0-nightly-20240820-0406-cc08f744.1",
21
+ "@fluentui-copilot/text-editor": "0.0.0-nightly-20240820-0406-cc08f744.1",
22
22
  "@swc/helpers": "^0.5.1"
23
23
  },
24
24
  "peerDependencies": {
@@ -1,44 +0,0 @@
1
- import { $isSentinelNode } from '@fluentui-copilot/chat-input-plugins';
2
- import { COMMAND_PRIORITY_CRITICAL, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, $getSelection, useLexicalComposerContext, $getLeafNodes, $getRoot, $isRangeSelection, mergeRegister } from '@fluentui-copilot/react-text-editor';
3
- import * as React from 'react';
4
- export const TextCursorPositionPlugin = ({
5
- setIsInLastPosition
6
- }) => {
7
- const [editor] = useLexicalComposerContext();
8
- const $keypressHandler = _ev => {
9
- const root = $getRoot();
10
- const leafNodes = $getLeafNodes(root);
11
- const lastLeafNode = leafNodes.length === 0 ? undefined : leafNodes[leafNodes.length - 1];
12
- const selection = $getSelection();
13
- if (selection === null || !$isRangeSelection(selection) || !selection.isCollapsed()) {
14
- setIsInLastPosition(false);
15
- return false;
16
- }
17
- const selectionNodes = selection.getNodes();
18
- // if we don't have a lead node, then we don't have any nodes, so we are in the last position
19
- if (selectionNodes.length === 0 || !lastLeafNode) {
20
- setIsInLastPosition(true);
21
- return false;
22
- }
23
- const lastSelectionNode = selectionNodes[selectionNodes.length - 1];
24
- // if the selection node is a sentinel and it matches the sentinel at the end
25
- if ($isSentinelNode(lastSelectionNode) && lastSelectionNode.is(lastLeafNode)) {
26
- setIsInLastPosition(true);
27
- return false;
28
- } else if ($isSentinelNode(lastSelectionNode.getNextSibling()) && selection.focus.offset === lastSelectionNode.getTextContentSize()) {
29
- setIsInLastPosition(true);
30
- return false;
31
- }
32
- setIsInLastPosition(false);
33
- return false;
34
- };
35
- React.useEffect(() => {
36
- return mergeRegister(editor.registerCommand(KEY_ARROW_DOWN_COMMAND, $keypressHandler, COMMAND_PRIORITY_CRITICAL), editor.registerCommand(KEY_ARROW_UP_COMMAND, $keypressHandler, COMMAND_PRIORITY_CRITICAL));
37
- // We are disabling exhaustive-deps because we only want to register the command once on mount and the
38
- // the teardown function when unmounting
39
- // eslint-disable-next-line react-compiler/react-compiler
40
- // eslint-disable-next-line react-hooks/exhaustive-deps
41
- }, []);
42
- return null;
43
- };
44
- //# sourceMappingURL=TextCursorPositionPlugin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["TextCursorPositionPlugin.ts"],"sourcesContent":["import { $isSentinelNode } from '@fluentui-copilot/chat-input-plugins';\nimport {\n COMMAND_PRIORITY_CRITICAL,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n $getSelection,\n useLexicalComposerContext,\n $getLeafNodes,\n $getRoot,\n $isRangeSelection,\n mergeRegister,\n} from '@fluentui-copilot/react-text-editor';\nimport * as React from 'react';\n\nexport type TextCursorPositionPluginProps = {\n setIsInLastPosition: (isInLastPosition: boolean) => void;\n};\n\nexport const TextCursorPositionPlugin: React.FunctionComponent<TextCursorPositionPluginProps> = ({\n setIsInLastPosition,\n}) => {\n const [editor] = useLexicalComposerContext();\n\n const $keypressHandler = (_ev: KeyboardEvent) => {\n const root = $getRoot();\n const leafNodes = $getLeafNodes(root);\n const lastLeafNode = leafNodes.length === 0 ? undefined : leafNodes[leafNodes.length - 1];\n const selection = $getSelection();\n if (selection === null || !$isRangeSelection(selection) || !selection.isCollapsed()) {\n setIsInLastPosition(false);\n return false;\n }\n\n const selectionNodes = selection.getNodes();\n // if we don't have a lead node, then we don't have any nodes, so we are in the last position\n if (selectionNodes.length === 0 || !lastLeafNode) {\n setIsInLastPosition(true);\n return false;\n }\n const lastSelectionNode = selectionNodes[selectionNodes.length - 1];\n\n // if the selection node is a sentinel and it matches the sentinel at the end\n if ($isSentinelNode(lastSelectionNode) && lastSelectionNode.is(lastLeafNode)) {\n setIsInLastPosition(true);\n return false;\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(lastSelectionNode.getNextSibling()) &&\n selection.focus.offset === lastSelectionNode.getTextContentSize()\n ) {\n setIsInLastPosition(true);\n return false;\n }\n\n setIsInLastPosition(false);\n return false;\n };\n\n React.useEffect(() => {\n return mergeRegister(\n editor.registerCommand(KEY_ARROW_DOWN_COMMAND, $keypressHandler, COMMAND_PRIORITY_CRITICAL),\n editor.registerCommand(KEY_ARROW_UP_COMMAND, $keypressHandler, COMMAND_PRIORITY_CRITICAL),\n );\n // We are disabling exhaustive-deps because we only want to register the command once on mount and the\n // the teardown function when unmounting\n // eslint-disable-next-line react-compiler/react-compiler\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return null;\n};\n"],"names":["$isSentinelNode","COMMAND_PRIORITY_CRITICAL","KEY_ARROW_DOWN_COMMAND","KEY_ARROW_UP_COMMAND","$getSelection","useLexicalComposerContext","$getLeafNodes","$getRoot","$isRangeSelection","mergeRegister","React","TextCursorPositionPlugin","setIsInLastPosition","editor","$keypressHandler","_ev","root","leafNodes","lastLeafNode","length","undefined","selection","isCollapsed","selectionNodes","getNodes","lastSelectionNode","is","getNextSibling","focus","offset","getTextContentSize","useEffect","registerCommand"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,eAAe,QAAQ,uCAAuC;AACvE,SACEC,yBAAyB,EACzBC,sBAAsB,EACtBC,oBAAoB,EACpBC,aAAa,EACbC,yBAAyB,EACzBC,aAAa,EACbC,QAAQ,EACRC,iBAAiB,EACjBC,aAAa,QACR,sCAAsC;AAC7C,YAAYC,WAAW,QAAQ;AAM/B,OAAO,MAAMC,2BAAmF,CAAC,EAC/FC,mBAAmB,EACpB;IACC,MAAM,CAACC,OAAO,GAAGR;IAEjB,MAAMS,mBAAmB,CAACC;QACxB,MAAMC,OAAOT;QACb,MAAMU,YAAYX,cAAcU;QAChC,MAAME,eAAeD,UAAUE,MAAM,KAAK,IAAIC,YAAYH,SAAS,CAACA,UAAUE,MAAM,GAAG,EAAE;QACzF,MAAME,YAAYjB;QAClB,IAAIiB,cAAc,QAAQ,CAACb,kBAAkBa,cAAc,CAACA,UAAUC,WAAW,IAAI;YACnFV,oBAAoB;YACpB,OAAO;QACT;QAEA,MAAMW,iBAAiBF,UAAUG,QAAQ;QACzC,6FAA6F;QAC7F,IAAID,eAAeJ,MAAM,KAAK,KAAK,CAACD,cAAc;YAChDN,oBAAoB;YACpB,OAAO;QACT;QACA,MAAMa,oBAAoBF,cAAc,CAACA,eAAeJ,MAAM,GAAG,EAAE;QAEnE,6EAA6E;QAC7E,IAAInB,gBAAgByB,sBAAsBA,kBAAkBC,EAAE,CAACR,eAAe;YAC5EN,oBAAoB;YACpB,OAAO;QACT,OAGK,IACHZ,gBAAgByB,kBAAkBE,cAAc,OAChDN,UAAUO,KAAK,CAACC,MAAM,KAAKJ,kBAAkBK,kBAAkB,IAC/D;YACAlB,oBAAoB;YACpB,OAAO;QACT;QAEAA,oBAAoB;QACpB,OAAO;IACT;IAEAF,MAAMqB,SAAS,CAAC;QACd,OAAOtB,cACLI,OAAOmB,eAAe,CAAC9B,wBAAwBY,kBAAkBb,4BACjEY,OAAOmB,eAAe,CAAC7B,sBAAsBW,kBAAkBb;IAEjE,sGAAsG;IACtG,wCAAwC;IACxC,yDAAyD;IACzD,uDAAuD;IACzD,GAAG,EAAE;IAEL,OAAO;AACT,EAAE"}
@@ -1,52 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "TextCursorPositionPlugin", {
6
- enumerable: true,
7
- get: function() {
8
- return TextCursorPositionPlugin;
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 TextCursorPositionPlugin = ({ setIsInLastPosition })=>{
16
- const [editor] = (0, _reacttexteditor.useLexicalComposerContext)();
17
- const $keypressHandler = (_ev)=>{
18
- const root = (0, _reacttexteditor.$getRoot)();
19
- const leafNodes = (0, _reacttexteditor.$getLeafNodes)(root);
20
- const lastLeafNode = leafNodes.length === 0 ? undefined : leafNodes[leafNodes.length - 1];
21
- const selection = (0, _reacttexteditor.$getSelection)();
22
- if (selection === null || !(0, _reacttexteditor.$isRangeSelection)(selection) || !selection.isCollapsed()) {
23
- setIsInLastPosition(false);
24
- return false;
25
- }
26
- const selectionNodes = selection.getNodes();
27
- // if we don't have a lead node, then we don't have any nodes, so we are in the last position
28
- if (selectionNodes.length === 0 || !lastLeafNode) {
29
- setIsInLastPosition(true);
30
- return false;
31
- }
32
- const lastSelectionNode = selectionNodes[selectionNodes.length - 1];
33
- // if the selection node is a sentinel and it matches the sentinel at the end
34
- if ((0, _chatinputplugins.$isSentinelNode)(lastSelectionNode) && lastSelectionNode.is(lastLeafNode)) {
35
- setIsInLastPosition(true);
36
- return false;
37
- } else if ((0, _chatinputplugins.$isSentinelNode)(lastSelectionNode.getNextSibling()) && selection.focus.offset === lastSelectionNode.getTextContentSize()) {
38
- setIsInLastPosition(true);
39
- return false;
40
- }
41
- setIsInLastPosition(false);
42
- return false;
43
- };
44
- _react.useEffect(()=>{
45
- return (0, _reacttexteditor.mergeRegister)(editor.registerCommand(_reacttexteditor.KEY_ARROW_DOWN_COMMAND, $keypressHandler, _reacttexteditor.COMMAND_PRIORITY_CRITICAL), editor.registerCommand(_reacttexteditor.KEY_ARROW_UP_COMMAND, $keypressHandler, _reacttexteditor.COMMAND_PRIORITY_CRITICAL));
46
- // We are disabling exhaustive-deps because we only want to register the command once on mount and the
47
- // the teardown function when unmounting
48
- // eslint-disable-next-line react-compiler/react-compiler
49
- // eslint-disable-next-line react-hooks/exhaustive-deps
50
- }, []);
51
- return null;
52
- }; //# sourceMappingURL=TextCursorPositionPlugin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["TextCursorPositionPlugin.ts"],"sourcesContent":["import { $isSentinelNode } from '@fluentui-copilot/chat-input-plugins';\nimport {\n COMMAND_PRIORITY_CRITICAL,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n $getSelection,\n useLexicalComposerContext,\n $getLeafNodes,\n $getRoot,\n $isRangeSelection,\n mergeRegister,\n} from '@fluentui-copilot/react-text-editor';\nimport * as React from 'react';\n\nexport type TextCursorPositionPluginProps = {\n setIsInLastPosition: (isInLastPosition: boolean) => void;\n};\n\nexport const TextCursorPositionPlugin: React.FunctionComponent<TextCursorPositionPluginProps> = ({\n setIsInLastPosition,\n}) => {\n const [editor] = useLexicalComposerContext();\n\n const $keypressHandler = (_ev: KeyboardEvent) => {\n const root = $getRoot();\n const leafNodes = $getLeafNodes(root);\n const lastLeafNode = leafNodes.length === 0 ? undefined : leafNodes[leafNodes.length - 1];\n const selection = $getSelection();\n if (selection === null || !$isRangeSelection(selection) || !selection.isCollapsed()) {\n setIsInLastPosition(false);\n return false;\n }\n\n const selectionNodes = selection.getNodes();\n // if we don't have a lead node, then we don't have any nodes, so we are in the last position\n if (selectionNodes.length === 0 || !lastLeafNode) {\n setIsInLastPosition(true);\n return false;\n }\n const lastSelectionNode = selectionNodes[selectionNodes.length - 1];\n\n // if the selection node is a sentinel and it matches the sentinel at the end\n if ($isSentinelNode(lastSelectionNode) && lastSelectionNode.is(lastLeafNode)) {\n setIsInLastPosition(true);\n return false;\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(lastSelectionNode.getNextSibling()) &&\n selection.focus.offset === lastSelectionNode.getTextContentSize()\n ) {\n setIsInLastPosition(true);\n return false;\n }\n\n setIsInLastPosition(false);\n return false;\n };\n\n React.useEffect(() => {\n return mergeRegister(\n editor.registerCommand(KEY_ARROW_DOWN_COMMAND, $keypressHandler, COMMAND_PRIORITY_CRITICAL),\n editor.registerCommand(KEY_ARROW_UP_COMMAND, $keypressHandler, COMMAND_PRIORITY_CRITICAL),\n );\n // We are disabling exhaustive-deps because we only want to register the command once on mount and the\n // the teardown function when unmounting\n // eslint-disable-next-line react-compiler/react-compiler\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return null;\n};\n"],"names":["TextCursorPositionPlugin","useLexicalComposerContext","editor","root","$getRoot","$keypressHandler","$getLeafNodes","lastLeafNode","leafNodes","selection","$getSelection","$isRangeSelection","isCollapsed","setIsInLastPosition","selectionNodes","length","getNodes","lastSelectionNode","is","$isSentinelNode","getNextSibling","focus","offset","getTextContentSize","React","useEffect","mergeRegister","registerCommand","KEY_ARROW_DOWN_COMMAND","COMMAND_PRIORITY_CRITICAL","KEY_ARROW_UP_COMMAND"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAkBaA;;;eAAAA;;;;kCAlBmB;iCAWzB;iEACgB;AAMhB,MAAMA,2BAAmF,CAAC,qBAG9EC;UAGf,CAAAC,OAAMC,GAAAA,IAAAA,0CAAOC;UACbC,mBAAkBC,CAAAA;cAClBH,OAAMI,IAAAA,yBAAAA;cACNC,YAAMC,IAAAA,8BAAYC,EAAAA;cAClBH,eAAIE,UAAuBE,MAAAA,KAAAA,IAAAA,YAAkBF,SAAeA,CAAAA,UAAUG,MAAAA,GAAW,EAAI;0BACnFC,IAAAA,8BAAoB;0BACb,QAAA,CAAAF,IAAAA,kCAAA,EAAAF,cAAA,CAAAA,UAAAG,WAAA,IAAA;gCACT;mBAEA;;cAEAE,iBAAmBC,UAAMC,QAAWT;qGACd;2BACbQ,MAAA,KAAA,KAAA,CAAAR,cAAA;gCACT;mBACA;;cAGAU,oBAAoBA,cAAAA,CAAAA,eAAsBA,MAAAA,GAAkBC,EAAGX;qFACzC;iDACb,EAAAU,sBAAAA,kBAAAC,EAAA,CAAAX,eAAA;gCAKPY;mBAGAN;mBACAM,IAAAA,iCAAO,EAAAF,kBAAAG,cAAA,OAAAX,UAAAY,KAAA,CAAAC,MAAA,KAAAL,kBAAAM,kBAAA,IAAA;gCACT;mBAEAV;;QAEFA,oBAAA;QAEAW,OAAMC;;WAKJA,SAAA,CAAA;QACA,OAAAC,IAAAA,8BAAA,EAAAxB,OAAAyB,eAAwC,CAAAC,uCAAA,EAAAvB,kBAAAwB,0CAAA,GAAA3B,OAAAyB,eAAA,CAAAG,qCAAA,EAAAzB,kBAAAwB,0CAAA;IACxC,sGAAyD;IACzD,wCAAA;IACF,yDAAK;IAEL,uDAAO;IACP,GAAA,EAAA"}