@fluentui-copilot/react-prompt-listbox 0.7.0 → 0.7.2-hotfix.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 (82) hide show
  1. package/CHANGELOG.json +36 -0
  2. package/CHANGELOG.md +20 -1
  3. package/dist/index.d.ts +4 -5
  4. package/lib/PromptListbox.js +0 -1
  5. package/lib/PromptOption.js +0 -1
  6. package/lib/components/PromptListbox/PromptListbox.js +5 -7
  7. package/lib/components/PromptListbox/PromptListbox.types.js +1 -2
  8. package/lib/components/PromptListbox/index.js +0 -1
  9. package/lib/components/PromptListbox/renderPromptListbox.js +17 -21
  10. package/lib/components/PromptListbox/usePromptListbox.js +53 -67
  11. package/lib/components/PromptListbox/usePromptListboxContextValues.js +22 -30
  12. package/lib/components/PromptListbox/usePromptListboxStyles.styles.raw.js +31 -0
  13. package/lib/components/PromptListbox/usePromptListboxStyles.styles.raw.js.map +1 -0
  14. package/lib/components/PromptOption/PromptOption.js +4 -6
  15. package/lib/components/PromptOption/PromptOption.types.js +1 -2
  16. package/lib/components/PromptOption/index.js +0 -1
  17. package/lib/components/PromptOption/renderPromptOption.js +4 -6
  18. package/lib/components/PromptOption/usePromptOption.js +84 -84
  19. package/lib/components/PromptOption/usePromptOptionStyles.styles.raw.js +68 -0
  20. package/lib/components/PromptOption/usePromptOptionStyles.styles.raw.js.map +1 -0
  21. package/lib/components/motion/PromptListboxMotion.js +52 -50
  22. package/lib/components/utils/OptionCollection.types.js +1 -2
  23. package/lib/components/utils/PromptListboxFunctionality.types.js +1 -2
  24. package/lib/components/utils/PromptListboxFunctionality.types.js.map +1 -1
  25. package/lib/components/utils/Selection.types.js +1 -2
  26. package/lib/components/utils/dropdownKeyActions.js +49 -60
  27. package/lib/components/utils/useListboxPositioning.js +22 -24
  28. package/lib/components/utils/useOptionCollection.js +30 -32
  29. package/lib/components/utils/usePromptListboxFunctionality.js +121 -123
  30. package/lib/components/utils/usePromptListboxFunctionalityV2.js +109 -124
  31. package/lib/components/utils/useSelection.js +57 -49
  32. package/lib/components/utils/useTriggerKeyDown.js +124 -133
  33. package/lib/index.js +0 -1
  34. package/lib/plugins/CursorPositionPlugin.js +39 -39
  35. package/lib-commonjs/PromptListbox.js +0 -1
  36. package/lib-commonjs/PromptOption.js +0 -1
  37. package/lib-commonjs/components/PromptListbox/PromptListbox.js +1 -1
  38. package/lib-commonjs/components/PromptListbox/PromptListbox.js.map +1 -1
  39. package/lib-commonjs/components/PromptListbox/PromptListbox.types.js +0 -1
  40. package/lib-commonjs/components/PromptListbox/index.js +0 -1
  41. package/lib-commonjs/components/PromptListbox/renderPromptListbox.js +1 -1
  42. package/lib-commonjs/components/PromptListbox/renderPromptListbox.js.map +1 -1
  43. package/lib-commonjs/components/PromptListbox/usePromptListbox.js +1 -1
  44. package/lib-commonjs/components/PromptListbox/usePromptListbox.js.map +1 -1
  45. package/lib-commonjs/components/PromptListbox/usePromptListboxContextValues.js +1 -1
  46. package/lib-commonjs/components/PromptListbox/usePromptListboxContextValues.js.map +1 -1
  47. package/lib-commonjs/components/PromptListbox/usePromptListboxStyles.styles.raw.js +47 -0
  48. package/lib-commonjs/components/PromptListbox/usePromptListboxStyles.styles.raw.js.map +1 -0
  49. package/lib-commonjs/components/PromptOption/PromptOption.js +1 -1
  50. package/lib-commonjs/components/PromptOption/PromptOption.js.map +1 -1
  51. package/lib-commonjs/components/PromptOption/PromptOption.types.js +0 -1
  52. package/lib-commonjs/components/PromptOption/index.js +0 -1
  53. package/lib-commonjs/components/PromptOption/renderPromptOption.js +1 -1
  54. package/lib-commonjs/components/PromptOption/renderPromptOption.js.map +1 -1
  55. package/lib-commonjs/components/PromptOption/usePromptOption.js +1 -1
  56. package/lib-commonjs/components/PromptOption/usePromptOption.js.map +1 -1
  57. package/lib-commonjs/components/PromptOption/usePromptOptionStyles.styles.raw.js +84 -0
  58. package/lib-commonjs/components/PromptOption/usePromptOptionStyles.styles.raw.js.map +1 -0
  59. package/lib-commonjs/components/motion/PromptListboxMotion.js +1 -1
  60. package/lib-commonjs/components/motion/PromptListboxMotion.js.map +1 -1
  61. package/lib-commonjs/components/utils/OptionCollection.types.js +0 -1
  62. package/lib-commonjs/components/utils/PromptListboxFunctionality.types.js +0 -1
  63. package/lib-commonjs/components/utils/PromptListboxFunctionality.types.js.map +1 -1
  64. package/lib-commonjs/components/utils/Selection.types.js +0 -1
  65. package/lib-commonjs/components/utils/dropdownKeyActions.js +1 -1
  66. package/lib-commonjs/components/utils/dropdownKeyActions.js.map +1 -1
  67. package/lib-commonjs/components/utils/useListboxPositioning.js +1 -1
  68. package/lib-commonjs/components/utils/useListboxPositioning.js.map +1 -1
  69. package/lib-commonjs/components/utils/useOptionCollection.js +1 -1
  70. package/lib-commonjs/components/utils/useOptionCollection.js.map +1 -1
  71. package/lib-commonjs/components/utils/usePromptListboxFunctionality.js +1 -1
  72. package/lib-commonjs/components/utils/usePromptListboxFunctionality.js.map +1 -1
  73. package/lib-commonjs/components/utils/usePromptListboxFunctionalityV2.js +1 -1
  74. package/lib-commonjs/components/utils/usePromptListboxFunctionalityV2.js.map +1 -1
  75. package/lib-commonjs/components/utils/useSelection.js +1 -1
  76. package/lib-commonjs/components/utils/useSelection.js.map +1 -1
  77. package/lib-commonjs/components/utils/useTriggerKeyDown.js +1 -1
  78. package/lib-commonjs/components/utils/useTriggerKeyDown.js.map +1 -1
  79. package/lib-commonjs/index.js +0 -1
  80. package/lib-commonjs/plugins/CursorPositionPlugin.js +1 -1
  81. package/lib-commonjs/plugins/CursorPositionPlugin.js.map +1 -1
  82. package/package.json +21 -24
@@ -11,91 +11,91 @@ import { useListboxContext_unstable } from '@fluentui/react-combobox';
11
11
  *
12
12
  * @param props - props from this instance of PromptOption
13
13
  * @param ref - reference to root HTMLElement of PromptOption
14
- */
15
- export const usePromptOption_unstable = (props, ref) => {
16
- const {
17
- controller: activeDescendantController
18
- } = useActiveDescendantContext();
19
- const {
20
- children,
21
- disabled,
22
- text,
23
- value
24
- } = props;
25
- const optionRef = React.useRef(null);
26
- const optionText = getTextString(text, children);
27
- const optionValue = value !== null && value !== void 0 ? value : optionText;
28
- // use the id if provided, otherwise use a generated id
29
- const id = useId('fluent-option', props.id);
30
- // data used for context registration & events
31
- const optionData = React.useMemo(() => ({
32
- id,
33
- disabled,
34
- text: optionText,
35
- value: optionValue
36
- }), [id, disabled, optionText, optionValue]);
37
- // context values
38
- const registerOption = useListboxContext_unstable(ctx => ctx.registerOption);
39
- const selected = useListboxContext_unstable(ctx => {
40
- const selectedOptions = ctx.selectedOptions;
41
- return optionValue !== undefined && selectedOptions.find(o => o === optionValue) !== undefined;
42
- });
43
- const selectOption = useListboxContext_unstable(ctx => ctx.selectOption);
44
- const onOptionClick = useListboxContext_unstable(ctx => ctx.onOptionClick);
45
- const onClick = event => {
46
- var _props_onClick;
47
- if (disabled) {
48
- event.preventDefault();
49
- return;
50
- }
51
- activeDescendantController.focus(id);
52
- // handle selection change
53
- selectOption(event, optionData);
54
- onOptionClick(event);
55
- (_props_onClick = props.onClick) === null || _props_onClick === void 0 ? void 0 : _props_onClick.call(props, event);
56
- };
57
- // register option data with context
58
- React.useEffect(() => {
59
- if (id && optionRef.current) {
60
- return registerOption(optionData, optionRef.current);
61
- }
62
- }, [id, optionData, registerOption]);
63
- return {
64
- components: {
65
- root: 'div'
66
- },
67
- root: slot.always(getIntrinsicElementProps('div', {
68
- ref: useMergedRefs(ref, optionRef),
69
- 'aria-disabled': disabled ? true : undefined,
70
- id,
71
- role: 'option',
72
- ...props,
73
- onClick
74
- }), {
75
- elementType: 'div'
76
- }),
77
- disabled,
78
- selected
79
- };
14
+ */ export const usePromptOption_unstable = (props, ref)=>{
15
+ const { controller: activeDescendantController } = useActiveDescendantContext();
16
+ const { children, disabled, text, value } = props;
17
+ const optionRef = React.useRef(null);
18
+ const optionText = getTextString(text, children);
19
+ const optionValue = value !== null && value !== void 0 ? value : optionText;
20
+ // use the id if provided, otherwise use a generated id
21
+ const id = useId('fluent-option', props.id);
22
+ // data used for context registration & events
23
+ const optionData = React.useMemo(()=>({
24
+ id,
25
+ disabled,
26
+ text: optionText,
27
+ value: optionValue
28
+ }), [
29
+ id,
30
+ disabled,
31
+ optionText,
32
+ optionValue
33
+ ]);
34
+ // context values
35
+ const registerOption = useListboxContext_unstable((ctx)=>ctx.registerOption);
36
+ const selected = useListboxContext_unstable((ctx)=>{
37
+ const selectedOptions = ctx.selectedOptions;
38
+ return optionValue !== undefined && selectedOptions.find((o)=>o === optionValue) !== undefined;
39
+ });
40
+ const selectOption = useListboxContext_unstable((ctx)=>ctx.selectOption);
41
+ const onOptionClick = useListboxContext_unstable((ctx)=>ctx.onOptionClick);
42
+ const onClick = (event)=>{
43
+ var _props_onClick;
44
+ if (disabled) {
45
+ event.preventDefault();
46
+ return;
47
+ }
48
+ activeDescendantController.focus(id);
49
+ // handle selection change
50
+ selectOption(event, optionData);
51
+ onOptionClick(event);
52
+ (_props_onClick = props.onClick) === null || _props_onClick === void 0 ? void 0 : _props_onClick.call(props, event);
53
+ };
54
+ // register option data with context
55
+ React.useEffect(()=>{
56
+ if (id && optionRef.current) {
57
+ return registerOption(optionData, optionRef.current);
58
+ }
59
+ }, [
60
+ id,
61
+ optionData,
62
+ registerOption
63
+ ]);
64
+ return {
65
+ components: {
66
+ root: 'div'
67
+ },
68
+ root: slot.always(getIntrinsicElementProps('div', {
69
+ ref: useMergedRefs(ref, optionRef),
70
+ 'aria-disabled': disabled ? true : undefined,
71
+ id,
72
+ role: 'option',
73
+ ...props,
74
+ onClick
75
+ }), {
76
+ elementType: 'div'
77
+ }),
78
+ disabled,
79
+ selected
80
+ };
80
81
  };
81
82
  function getTextString(text, children) {
82
- if (text !== undefined) {
83
- return text;
84
- }
85
- let textString = '';
86
- let hasNonStringChild = false;
87
- React.Children.forEach(children, child => {
88
- if (typeof child === 'string') {
89
- textString += child;
90
- } else {
91
- hasNonStringChild = true;
83
+ if (text !== undefined) {
84
+ return text;
85
+ }
86
+ let textString = '';
87
+ let hasNonStringChild = false;
88
+ React.Children.forEach(children, (child)=>{
89
+ if (typeof child === 'string') {
90
+ textString += child;
91
+ } else {
92
+ hasNonStringChild = true;
93
+ }
94
+ });
95
+ // warn if an Option has non-string children and no text prop
96
+ if (hasNonStringChild) {
97
+ // eslint-disable-next-line no-console
98
+ console.warn('Provide a `text` prop to Option components when they contain non-string children.');
92
99
  }
93
- });
94
- // warn if an Option has non-string children and no text prop
95
- if (hasNonStringChild) {
96
- // eslint-disable-next-line no-console
97
- console.warn('Provide a `text` prop to Option components when they contain non-string children.');
98
- }
99
- return textString;
100
+ return textString;
100
101
  }
101
- //# sourceMappingURL=usePromptOption.js.map
@@ -0,0 +1,68 @@
1
+ import { makeStyles, mergeClasses, shorthands } from '@fluentui/react-components';
2
+ import { tokens } from '@fluentui-copilot/tokens';
3
+ import { ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from '@fluentui/react-aria';
4
+ export const promptOptionClassNames = {
5
+ root: 'fai-PromptOption'
6
+ };
7
+ /**
8
+ * Styles for the root slot
9
+ */ const useStyles = makeStyles({
10
+ root: {
11
+ alignItems: 'center',
12
+ borderRadius: tokens.borderRadiusMedium,
13
+ color: tokens.colorNeutralForeground1,
14
+ columnGap: tokens.spacingHorizontalXS,
15
+ cursor: 'pointer',
16
+ display: 'flex',
17
+ fontFamily: tokens.fontFamilyBase,
18
+ fontSize: tokens.fontSizeBase300,
19
+ lineHeight: tokens.lineHeightBase300,
20
+ padding: `${tokens.spacingVerticalSNudge} ${tokens.spacingHorizontalS}`,
21
+ position: 'relative',
22
+ ':hover': {
23
+ backgroundColor: tokens.colorNeutralBackground1Hover,
24
+ color: tokens.colorNeutralForeground1Hover
25
+ },
26
+ ':active': {
27
+ backgroundColor: tokens.colorNeutralBackground1Pressed,
28
+ color: tokens.colorNeutralForeground1Pressed
29
+ }
30
+ },
31
+ active: {
32
+ [`[${ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE}]::after`]: {
33
+ content: '""',
34
+ position: 'absolute',
35
+ pointerEvents: 'none',
36
+ zIndex: 1,
37
+ ...shorthands.border(tokens.strokeWidthThick, `solid`, tokens.colorStrokeFocus2),
38
+ borderRadius: tokens.borderRadiusMedium,
39
+ top: '-2px',
40
+ bottom: '-2px',
41
+ left: '-2px',
42
+ right: '-2px'
43
+ }
44
+ },
45
+ disabled: {
46
+ color: tokens.colorNeutralForegroundDisabled,
47
+ ':hover': {
48
+ backgroundColor: tokens.colorTransparentBackground,
49
+ color: tokens.colorNeutralForegroundDisabled
50
+ },
51
+ ':active': {
52
+ backgroundColor: tokens.colorTransparentBackground,
53
+ color: tokens.colorNeutralForegroundDisabled
54
+ },
55
+ '@media (forced-colors: active)': {
56
+ color: 'GrayText'
57
+ }
58
+ }
59
+ });
60
+ /**
61
+ * Apply styling to the PromptOption slots based on the state
62
+ */ export const usePromptOptionStyles_unstable = (state)=>{
63
+ 'use no memo';
64
+ const { disabled } = state;
65
+ const styles = useStyles();
66
+ state.root.className = mergeClasses(promptOptionClassNames.root, styles.root, styles.active, disabled && styles.disabled, state.root.className);
67
+ return state;
68
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["usePromptOptionStyles.styles.ts"],"sourcesContent":["import { makeStyles, mergeClasses, shorthands } from '@fluentui/react-components';\nimport { tokens } from '@fluentui-copilot/tokens';\nimport { ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from '@fluentui/react-aria';\nimport type { PromptOptionSlots, PromptOptionState } from './PromptOption.types';\nimport type { SlotClassNames } from '@fluentui/react-components';\n\nexport const promptOptionClassNames: SlotClassNames<PromptOptionSlots> = {\n root: 'fai-PromptOption',\n};\n\n/**\n * Styles for the root slot\n */\nconst useStyles = makeStyles({\n root: {\n alignItems: 'center',\n borderRadius: tokens.borderRadiusMedium,\n color: tokens.colorNeutralForeground1,\n columnGap: tokens.spacingHorizontalXS,\n cursor: 'pointer',\n display: 'flex',\n fontFamily: tokens.fontFamilyBase,\n fontSize: tokens.fontSizeBase300,\n lineHeight: tokens.lineHeightBase300,\n padding: `${tokens.spacingVerticalSNudge} ${tokens.spacingHorizontalS}`,\n position: 'relative',\n\n ':hover': {\n backgroundColor: tokens.colorNeutralBackground1Hover,\n color: tokens.colorNeutralForeground1Hover,\n },\n\n ':active': {\n backgroundColor: tokens.colorNeutralBackground1Pressed,\n color: tokens.colorNeutralForeground1Pressed,\n },\n },\n\n active: {\n [`[${ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE}]::after`]: {\n content: '\"\"',\n position: 'absolute',\n pointerEvents: 'none',\n zIndex: 1,\n\n ...shorthands.border(tokens.strokeWidthThick, `solid`, tokens.colorStrokeFocus2),\n borderRadius: tokens.borderRadiusMedium,\n\n top: '-2px',\n bottom: '-2px',\n left: '-2px',\n right: '-2px',\n },\n },\n\n disabled: {\n color: tokens.colorNeutralForegroundDisabled,\n\n ':hover': {\n backgroundColor: tokens.colorTransparentBackground,\n color: tokens.colorNeutralForegroundDisabled,\n },\n\n ':active': {\n backgroundColor: tokens.colorTransparentBackground,\n color: tokens.colorNeutralForegroundDisabled,\n },\n\n '@media (forced-colors: active)': {\n color: 'GrayText',\n },\n },\n});\n\n/**\n * Apply styling to the PromptOption slots based on the state\n */\nexport const usePromptOptionStyles_unstable = (state: PromptOptionState): PromptOptionState => {\n 'use no memo';\n\n const { disabled } = state;\n const styles = useStyles();\n state.root.className = mergeClasses(\n promptOptionClassNames.root,\n styles.root,\n styles.active,\n disabled && styles.disabled,\n state.root.className,\n );\n\n return state;\n};\n"],"names":["makeStyles","mergeClasses","shorthands","tokens","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","promptOptionClassNames","root","useStyles","alignItems","borderRadius","borderRadiusMedium","color","colorNeutralForeground1","columnGap","spacingHorizontalXS","cursor","display","fontFamily","fontFamilyBase","fontSize","fontSizeBase300","lineHeight","lineHeightBase300","padding","spacingVerticalSNudge","spacingHorizontalS","position","backgroundColor","colorNeutralBackground1Hover","colorNeutralForeground1Hover","colorNeutralBackground1Pressed","colorNeutralForeground1Pressed","active","content","pointerEvents","zIndex","border","strokeWidthThick","colorStrokeFocus2","top","bottom","left","right","disabled","colorNeutralForegroundDisabled","colorTransparentBackground","usePromptOptionStyles_unstable","state","styles","className"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,UAAU,EAAEC,YAAY,EAAEC,UAAU,QAAQ,6BAA6B;AAClF,SAASC,MAAM,QAAQ,2BAA2B;AAClD,SAASC,uCAAuC,QAAQ,uBAAuB;AAI/E,OAAO,MAAMC,yBAA4D;IACvEC,MAAM;AACR,EAAE;AAEF;;CAEC,GACD,MAAMC,YAAYP,WAAW;IAC3BM,MAAM;QACJE,YAAY;QACZC,cAAcN,OAAOO,kBAAkB;QACvCC,OAAOR,OAAOS,uBAAuB;QACrCC,WAAWV,OAAOW,mBAAmB;QACrCC,QAAQ;QACRC,SAAS;QACTC,YAAYd,OAAOe,cAAc;QACjCC,UAAUhB,OAAOiB,eAAe;QAChCC,YAAYlB,OAAOmB,iBAAiB;QACpCC,SAAS,CAAC,EAAEpB,OAAOqB,qBAAqB,CAAC,CAAC,EAAErB,OAAOsB,kBAAkB,CAAC,CAAC;QACvEC,UAAU;QAEV,UAAU;YACRC,iBAAiBxB,OAAOyB,4BAA4B;YACpDjB,OAAOR,OAAO0B,4BAA4B;QAC5C;QAEA,WAAW;YACTF,iBAAiBxB,OAAO2B,8BAA8B;YACtDnB,OAAOR,OAAO4B,8BAA8B;QAC9C;IACF;IAEAC,QAAQ;QACN,CAAC,CAAC,CAAC,EAAE5B,wCAAwC,QAAQ,CAAC,CAAC,EAAE;YACvD6B,SAAS;YACTP,UAAU;YACVQ,eAAe;YACfC,QAAQ;YAER,GAAGjC,WAAWkC,MAAM,CAACjC,OAAOkC,gBAAgB,EAAE,CAAC,KAAK,CAAC,EAAElC,OAAOmC,iBAAiB,CAAC;YAChF7B,cAAcN,OAAOO,kBAAkB;YAEvC6B,KAAK;YACLC,QAAQ;YACRC,MAAM;YACNC,OAAO;QACT;IACF;IAEAC,UAAU;QACRhC,OAAOR,OAAOyC,8BAA8B;QAE5C,UAAU;YACRjB,iBAAiBxB,OAAO0C,0BAA0B;YAClDlC,OAAOR,OAAOyC,8BAA8B;QAC9C;QAEA,WAAW;YACTjB,iBAAiBxB,OAAO0C,0BAA0B;YAClDlC,OAAOR,OAAOyC,8BAA8B;QAC9C;QAEA,kCAAkC;YAChCjC,OAAO;QACT;IACF;AACF;AAEA;;CAEC,GACD,OAAO,MAAMmC,iCAAiC,CAACC;IAC7C;IAEA,MAAM,EAAEJ,QAAQ,EAAE,GAAGI;IACrB,MAAMC,SAASzC;IACfwC,MAAMzC,IAAI,CAAC2C,SAAS,GAAGhD,aACrBI,uBAAuBC,IAAI,EAC3B0C,OAAO1C,IAAI,EACX0C,OAAOhB,MAAM,EACbW,YAAYK,OAAOL,QAAQ,EAC3BI,MAAMzC,IAAI,CAAC2C,SAAS;IAGtB,OAAOF;AACT,EAAE"}
@@ -1,53 +1,55 @@
1
1
  import { createPresenceComponent, motionTokens } from '@fluentui/react-components';
2
- const collapseMotion = ({
3
- element
4
- }) => {
5
- const fromOpacity = 0;
6
- const toOpacity = 1;
7
- const fromHeight = '0';
8
- const toHeight = `${element.scrollHeight}px`;
9
- const overflow = 'hidden';
10
- const duration = motionTokens.durationNormal;
11
- const easing = motionTokens.curveEasyEaseMax;
12
- const enterKeyframes = [{
13
- opacity: fromOpacity,
14
- maxHeight: fromHeight,
15
- overflow
16
- },
17
- // Transition to the height of the content, at 99.99% of the duration.
18
- {
19
- opacity: toOpacity,
20
- maxHeight: toHeight,
21
- offset: 0.9999,
22
- overflow
23
- },
24
- // On completion, remove the maxHeight because the content might need to expand later.
25
- {
26
- opacity: toOpacity,
27
- maxHeight: 'unset',
28
- overflow
29
- }];
30
- const exitKeyframes = [{
31
- opacity: toOpacity,
32
- maxHeight: toHeight,
33
- overflow
34
- }, {
35
- opacity: fromOpacity,
36
- maxHeight: fromHeight,
37
- overflow
38
- }];
39
- return {
40
- enter: {
41
- duration,
42
- easing,
43
- keyframes: enterKeyframes
44
- },
45
- exit: {
46
- duration,
47
- easing,
48
- keyframes: exitKeyframes
49
- }
50
- };
2
+ const collapseMotion = ({ element })=>{
3
+ const fromOpacity = 0;
4
+ const toOpacity = 1;
5
+ const fromHeight = '0';
6
+ const toHeight = `${element.scrollHeight}px`;
7
+ const overflow = 'hidden';
8
+ const duration = motionTokens.durationNormal;
9
+ const easing = motionTokens.curveEasyEaseMax;
10
+ const enterKeyframes = [
11
+ {
12
+ opacity: fromOpacity,
13
+ maxHeight: fromHeight,
14
+ overflow
15
+ },
16
+ // Transition to the height of the content, at 99.99% of the duration.
17
+ {
18
+ opacity: toOpacity,
19
+ maxHeight: toHeight,
20
+ offset: 0.9999,
21
+ overflow
22
+ },
23
+ // On completion, remove the maxHeight because the content might need to expand later.
24
+ {
25
+ opacity: toOpacity,
26
+ maxHeight: 'unset',
27
+ overflow
28
+ }
29
+ ];
30
+ const exitKeyframes = [
31
+ {
32
+ opacity: toOpacity,
33
+ maxHeight: toHeight,
34
+ overflow
35
+ },
36
+ {
37
+ opacity: fromOpacity,
38
+ maxHeight: fromHeight,
39
+ overflow
40
+ }
41
+ ];
42
+ return {
43
+ enter: {
44
+ duration,
45
+ easing,
46
+ keyframes: enterKeyframes
47
+ },
48
+ exit: {
49
+ duration,
50
+ easing,
51
+ keyframes: exitKeyframes
52
+ }
53
+ };
51
54
  };
52
55
  export const PromptListboxMotion = createPresenceComponent(collapseMotion);
53
- //# sourceMappingURL=PromptListboxMotion.js.map
@@ -1,3 +1,2 @@
1
1
  // Brought from Fluent UI
2
- export {};
3
- //# sourceMappingURL=OptionCollection.types.js.map
2
+ export { };
@@ -1,2 +1 @@
1
- export {};
2
- //# sourceMappingURL=PromptListboxFunctionality.types.js.map
1
+ export { };
@@ -1 +1 @@
1
- {"version":3,"sources":["PromptListboxFunctionality.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { PromptListboxProps } from '../../components/PromptListbox';\nimport type { PositioningShorthand } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\n\n// Note: While we are removing multiselect, we are keeping the logic and disabling it\n// in case it's needed in the future.\nexport type ProcessedPromptListboxProps = Partial<\n Omit<PromptListboxProps, 'activeDescendantController' | 'multiselect'>\n> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: React.MutableRefObject<any>;\n};\n\nexport type UsePromptListboxFunctionality = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSX.Element;\n /**\n * Props to be spread in the PromptInput, these props are needed for the keyboard behavior to\n * work correctly.\n */\n triggerProps: {\n ref: React.RefObject<HTMLSpanElement>;\n /**\n * Whether the listbox is being used to go through options or the user is currently typing.\n */\n isInSelectionMode: boolean;\n } & Required<Pick<EditorInputProps, 'onBlur' | 'onFocus' | 'onKeyDown'>>;\n /**\n * Ref used to point which element the listbox should be anchored to. Most use cases\n * will provide this prop to the PromptInput's EditorInput (since this is the root slot,\n * this is provided directly to the component and not the slot).\n *\n * Note: If the containerRef is the same as the trigger, the ref provided in triggerProps needs\n * to be merged with this one using `useMergedRefs(containerRef, triggerProps.ref);`\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n containerRef: React.MutableRefObject<any>;\n /**\n * Plugin used to tell where the cursor is in the EditorInput, this is important for the\n * keyboard behavior. This should be passed as children in the PromptInput.\n */\n cursorPositionPlugin: JSX.Element;\n};\n\nexport type UsePromptListboxFunctionalityParams = {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n positioning?: PositioningShorthand;\n\n /**\n * Callback to call when the selection mode (selecting an action vs typing) changes.\n */\n onSelectionModeChange?: (isInSelectionMode: boolean) => void;\n\n /**\n * Props to be passed to the ListboxComponent\n */\n listboxProps?: ProcessedPromptListboxProps;\n\n /**\n * Whether the listbox's width should take all the available space or only\n * the required space.\n *\n * @default false\n */\n fluid?: boolean;\n\n /**\n * Whether to allow reaching the listbox options by arrowing up at the start of the input.\n * Note, this prop is meant to be used with the following positioning props:\n * ```ts\n * usePromptListboxFunctionality({\n * positioning: {\n * position: 'above',\n * fallbackPositions: ['above']\n * }\n * });\n * ```\n * This is useful when using PromptListbox with other components such as ChatInput since\n * the input will always stay at the bottom therefore the listbox would always get cut.\n *\n * @default false\n */\n allowArrowUpNavigation?: boolean;\n};\n\nexport type OnOpenChangeData = (\n | EventData<'click', React.MouseEvent<HTMLSpanElement>>\n | EventData<'focus', React.FocusEvent<HTMLSpanElement>>\n | EventData<'keyboard', React.KeyboardEvent<HTMLSpanElement>>\n) & {\n open: boolean;\n};\n"],"names":[],"rangeMappings":"","mappings":"AA2FA,WAME"}
1
+ {"version":3,"sources":["PromptListboxFunctionality.types.ts"],"sourcesContent":["import type * as React from 'react';\nimport type { PromptListboxProps } from '../../components/PromptListbox';\nimport type { PositioningShorthand } from '@fluentui/react-components';\nimport type { EventData, EventHandler } from '@fluentui/react-utilities';\nimport type { EditorInputProps } from '@fluentui-copilot/react-editor-input';\n\n// Note: While we are removing multiselect, we are keeping the logic and disabling it\n// in case it's needed in the future.\nexport type ProcessedPromptListboxProps = Partial<\n Omit<PromptListboxProps, 'activeDescendantController' | 'multiselect'>\n> & {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ref?: React.MutableRefObject<any>;\n};\n\nexport type UsePromptListboxFunctionality = {\n /**\n * Component to be rendered in the Input component. This should be passed to the listbox prop.\n */\n promptListbox: JSX.Element;\n /**\n * Props to be spread in the PromptInput, these props are needed for the keyboard behavior to\n * work correctly.\n */\n triggerProps: {\n ref: React.RefObject<HTMLSpanElement>;\n /**\n * Whether the listbox is being used to go through options or the user is currently typing.\n */\n isInSelectionMode: boolean;\n } & Required<Pick<EditorInputProps, 'onBlur' | 'onFocus' | 'onKeyDown'>>;\n /**\n * Ref used to point which element the listbox should be anchored to. Most use cases\n * will provide this prop to the PromptInput's EditorInput (since this is the root slot,\n * this is provided directly to the component and not the slot).\n *\n * Note: If the containerRef is the same as the trigger, the ref provided in triggerProps needs\n * to be merged with this one using `useMergedRefs(containerRef, triggerProps.ref);`\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n containerRef: React.MutableRefObject<any>;\n /**\n * Plugin used to tell where the cursor is in the EditorInput, this is important for the\n * keyboard behavior. This should be passed as children in the PromptInput.\n */\n cursorPositionPlugin: JSX.Element;\n};\n\nexport type UsePromptListboxFunctionalityParams = {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: EventHandler<OnOpenChangeData>;\n positioning?: PositioningShorthand;\n\n /**\n * Callback to call when the selection mode (selecting an action vs typing) changes.\n */\n onSelectionModeChange?: (isInSelectionMode: boolean) => void;\n\n /**\n * Props to be passed to the ListboxComponent\n */\n listboxProps?: ProcessedPromptListboxProps;\n\n /**\n * Whether the listbox's width should take all the available space or only\n * the required space.\n *\n * @default false\n */\n fluid?: boolean;\n\n /**\n * Whether to allow reaching the listbox options by arrowing up at the start of the input.\n * Note, this prop is meant to be used with the following positioning props:\n * ```ts\n * usePromptListboxFunctionality({\n * positioning: {\n * position: 'above',\n * fallbackPositions: ['above']\n * }\n * });\n * ```\n * This is useful when using PromptListbox with other components such as ChatInput since\n * the input will always stay at the bottom therefore the listbox would always get cut.\n *\n * @default false\n */\n allowArrowUpNavigation?: boolean;\n};\n\nexport type OnOpenChangeData = (\n | EventData<'click', React.MouseEvent<HTMLSpanElement>>\n | EventData<'focus', React.FocusEvent<HTMLSpanElement>>\n | EventData<'keyboard', React.KeyboardEvent<HTMLSpanElement>>\n) & {\n open: boolean;\n};\n"],"names":[],"rangeMappings":"","mappings":"AA2FA,WAME"}
@@ -1,3 +1,2 @@
1
1
  // Brought from Fluent UI
2
- /** Possible event types for onOptionSelect */export {};
3
- //# sourceMappingURL=Selection.types.js.map
2
+ /** Possible event types for onOptionSelect */ export { };
@@ -1,68 +1,57 @@
1
1
  /**
2
2
  * Note, this is mainly brought from Fluent UI, only removed the closing and
3
3
  * opening logic since that's not needed for this use case.
4
- */import * as keys from '@fluentui/keyboard-keys';
4
+ */ import * as keys from '@fluentui/keyboard-keys';
5
5
  /**
6
6
  * Converts a keyboard interaction into a defined action
7
- */
8
- export function getDropdownActionFromKey(e, options) {
9
- const {
10
- cursorPosition,
11
- allowArrowUpNavigation,
12
- isInSelectionMode
13
- } = options;
14
- const code = e.key;
15
- const {
16
- altKey,
17
- ctrlKey,
18
- key,
19
- metaKey
20
- } = e;
21
- // typing action occurs whether open or closed
22
- if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {
23
- return 'Type';
24
- }
25
- // select or close actions
26
- if (code === keys.ArrowUp && altKey || code === keys.Enter) {
27
- return 'CloseSelect';
28
- }
29
- // navigation interactions
30
- const atStart = allowArrowUpNavigation && (cursorPosition === 'start' || cursorPosition === 'start-end');
31
- const atEnd = cursorPosition === 'end' || cursorPosition === 'start-end';
32
- if (code === keys.ArrowDown) {
33
- if (atEnd) {
34
- return 'Next';
35
- } else if (atStart && isInSelectionMode) {
36
- return 'Next';
7
+ */ export function getDropdownActionFromKey(e, options) {
8
+ const { cursorPosition, allowArrowUpNavigation, isInSelectionMode } = options;
9
+ const code = e.key;
10
+ const { altKey, ctrlKey, key, metaKey } = e;
11
+ // typing action occurs whether open or closed
12
+ if (key.length === 1 && code !== keys.Space && !altKey && !ctrlKey && !metaKey) {
13
+ return 'Type';
37
14
  }
38
- return 'Type';
39
- }
40
- if (code === keys.ArrowUp) {
41
- if (atEnd && isInSelectionMode) {
42
- return 'Previous';
43
- } else if (atStart && !isInSelectionMode) {
44
- return 'Next';
45
- } else if (atStart && isInSelectionMode) {
46
- return 'Previous';
15
+ // select or close actions
16
+ if (code === keys.ArrowUp && altKey || code === keys.Enter) {
17
+ return 'CloseSelect';
47
18
  }
48
- return 'Type';
49
- }
50
- if (code === keys.Home) {
51
- return atEnd || atStart ? 'First' : 'Type';
52
- }
53
- if (code === keys.End) {
54
- return atEnd || atStart ? 'Last' : 'Type';
55
- }
56
- if (code === keys.PageUp) {
57
- return 'PageUp';
58
- }
59
- if (code === keys.PageDown) {
60
- return 'PageDown';
61
- }
62
- if (code === keys.Tab) {
63
- return 'Tab';
64
- }
65
- // if nothing matched, return none
66
- return 'None';
19
+ // navigation interactions
20
+ const atStart = allowArrowUpNavigation && (cursorPosition === 'start' || cursorPosition === 'start-end');
21
+ const atEnd = cursorPosition === 'end' || cursorPosition === 'start-end';
22
+ if (code === keys.ArrowDown) {
23
+ if (atEnd) {
24
+ return 'Next';
25
+ } else if (atStart && isInSelectionMode) {
26
+ return 'Next';
27
+ }
28
+ return 'Type';
29
+ }
30
+ if (code === keys.ArrowUp) {
31
+ if (atEnd && isInSelectionMode) {
32
+ return 'Previous';
33
+ } else if (atStart && !isInSelectionMode) {
34
+ return 'Next';
35
+ } else if (atStart && isInSelectionMode) {
36
+ return 'Previous';
37
+ }
38
+ return 'Type';
39
+ }
40
+ if (code === keys.Home) {
41
+ return atEnd || atStart ? 'First' : 'Type';
42
+ }
43
+ if (code === keys.End) {
44
+ return atEnd || atStart ? 'Last' : 'Type';
45
+ }
46
+ if (code === keys.PageUp) {
47
+ return 'PageUp';
48
+ }
49
+ if (code === keys.PageDown) {
50
+ return 'PageDown';
51
+ }
52
+ if (code === keys.Tab) {
53
+ return 'Tab';
54
+ }
55
+ // if nothing matched, return none
56
+ return 'None';
67
57
  }
68
- //# sourceMappingURL=dropdownKeyActions.js.map
@@ -1,28 +1,26 @@
1
1
  // Brought from Fluent UI
2
2
  import { resolvePositioningShorthand, usePositioning } from '@fluentui/react-positioning';
3
3
  export function useListboxPositioning(props) {
4
- const {
5
- positioning,
6
- fluid
7
- } = props;
8
- const fallbackPositions = ['below'];
9
- // popper options
10
- const popperOptions = {
11
- position: 'below',
12
- align: 'start',
13
- offset: {
14
- crossAxis: 0,
15
- mainAxis: 2
16
- },
17
- fallbackPositions: fallbackPositions,
18
- matchTargetSize: fluid ? 'width' : undefined,
19
- autoSize: true,
20
- ...resolvePositioningShorthand(positioning)
21
- };
22
- const {
23
- containerRef: listboxRef,
24
- targetRef: anchorRef
25
- } = usePositioning(popperOptions);
26
- return [listboxRef, anchorRef];
4
+ const { positioning, fluid } = props;
5
+ const fallbackPositions = [
6
+ 'below'
7
+ ];
8
+ // popper options
9
+ const popperOptions = {
10
+ position: 'below',
11
+ align: 'start',
12
+ offset: {
13
+ crossAxis: 0,
14
+ mainAxis: 2
15
+ },
16
+ fallbackPositions: fallbackPositions,
17
+ matchTargetSize: fluid ? 'width' : undefined,
18
+ autoSize: true,
19
+ ...resolvePositioningShorthand(positioning)
20
+ };
21
+ const { containerRef: listboxRef, targetRef: anchorRef } = usePositioning(popperOptions);
22
+ return [
23
+ listboxRef,
24
+ anchorRef
25
+ ];
27
26
  }
28
- //# sourceMappingURL=useListboxPositioning.js.map
@@ -2,38 +2,36 @@
2
2
  import * as React from 'react';
3
3
  /**
4
4
  * A hook for managing a collection of child Options
5
- */
6
- export const useOptionCollection = () => {
7
- const optionsById = React.useRef(new Map());
8
- const collectionAPI = React.useMemo(() => {
9
- const getCount = () => optionsById.current.size;
10
- // index searches are no longer used
11
- const getOptionById = id => {
12
- return optionsById.current.get(id);
13
- };
14
- const getOptionsMatchingValue = matcher => {
15
- const matches = [];
16
- for (const option of optionsById.current.values()) {
17
- if (matcher(option.value)) {
18
- matches.push(option);
19
- }
20
- }
21
- return matches;
22
- };
5
+ */ export const useOptionCollection = ()=>{
6
+ const optionsById = React.useRef(new Map());
7
+ const collectionAPI = React.useMemo(()=>{
8
+ const getCount = ()=>optionsById.current.size;
9
+ // index searches are no longer used
10
+ const getOptionById = (id)=>{
11
+ return optionsById.current.get(id);
12
+ };
13
+ const getOptionsMatchingValue = (matcher)=>{
14
+ const matches = [];
15
+ for (const option of optionsById.current.values()){
16
+ if (matcher(option.value)) {
17
+ matches.push(option);
18
+ }
19
+ }
20
+ return matches;
21
+ };
22
+ return {
23
+ getCount,
24
+ getOptionById,
25
+ getOptionsMatchingValue
26
+ };
27
+ }, []);
28
+ const registerOption = React.useCallback((option)=>{
29
+ optionsById.current.set(option.id, option);
30
+ return ()=>optionsById.current.delete(option.id);
31
+ }, []);
23
32
  return {
24
- getCount,
25
- getOptionById,
26
- getOptionsMatchingValue
33
+ ...collectionAPI,
34
+ options: Array.from(optionsById.current.values()),
35
+ registerOption
27
36
  };
28
- }, []);
29
- const registerOption = React.useCallback(option => {
30
- optionsById.current.set(option.id, option);
31
- return () => optionsById.current.delete(option.id);
32
- }, []);
33
- return {
34
- ...collectionAPI,
35
- options: Array.from(optionsById.current.values()),
36
- registerOption
37
- };
38
37
  };
39
- //# sourceMappingURL=useOptionCollection.js.map