@sap-ux/ui-components 1.13.5 → 1.14.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 (263) hide show
  1. package/dist/components/Icons.d.ts +150 -150
  2. package/dist/components/Icons.js +628 -628
  3. package/dist/components/UIActionCallout/UIActionCallout.d.ts +64 -64
  4. package/dist/components/UIActionCallout/UIActionCallout.js +67 -67
  5. package/dist/components/UIActionCallout/index.d.ts +1 -1
  6. package/dist/components/UIActionCallout/index.js +17 -17
  7. package/dist/components/UIBreadcrumb/UIBreadcrumb.d.ts +23 -23
  8. package/dist/components/UIBreadcrumb/UIBreadcrumb.js +38 -38
  9. package/dist/components/UIBreadcrumb/index.d.ts +1 -1
  10. package/dist/components/UIBreadcrumb/index.js +17 -17
  11. package/dist/components/UIButton/UIActionButton.d.ts +23 -23
  12. package/dist/components/UIButton/UIActionButton.js +89 -89
  13. package/dist/components/UIButton/UIDefaultButton.d.ts +41 -23
  14. package/dist/components/UIButton/UIDefaultButton.d.ts.map +1 -1
  15. package/dist/components/UIButton/UIDefaultButton.js +255 -237
  16. package/dist/components/UIButton/UIDefaultButton.js.map +1 -1
  17. package/dist/components/UIButton/UIIconButton.d.ts +37 -37
  18. package/dist/components/UIButton/UIIconButton.js +106 -106
  19. package/dist/components/UIButton/UISmallButton.d.ts +34 -34
  20. package/dist/components/UIButton/UISmallButton.js +115 -115
  21. package/dist/components/UIButton/UISplitButton.d.ts +44 -44
  22. package/dist/components/UIButton/UISplitButton.js +86 -86
  23. package/dist/components/UIButton/index.d.ts +7 -7
  24. package/dist/components/UIButton/index.js +21 -21
  25. package/dist/components/UICallout/CalloutCollisionTransform.d.ts +54 -54
  26. package/dist/components/UICallout/CalloutCollisionTransform.js +160 -160
  27. package/dist/components/UICallout/UICallout.d.ts +48 -48
  28. package/dist/components/UICallout/UICallout.js +122 -122
  29. package/dist/components/UICallout/index.d.ts +2 -2
  30. package/dist/components/UICallout/index.js +18 -18
  31. package/dist/components/UICheckbox/UICheckbox.d.ts +34 -34
  32. package/dist/components/UICheckbox/UICheckbox.js +135 -135
  33. package/dist/components/UICheckbox/index.d.ts +1 -1
  34. package/dist/components/UICheckbox/index.js +17 -17
  35. package/dist/components/UIChoiceGroup/UIChoiceGroup.d.ts +28 -28
  36. package/dist/components/UIChoiceGroup/UIChoiceGroup.js +182 -182
  37. package/dist/components/UIChoiceGroup/index.d.ts +1 -1
  38. package/dist/components/UIChoiceGroup/index.js +17 -17
  39. package/dist/components/UIComboBox/UIComboBox.d.ts +208 -200
  40. package/dist/components/UIComboBox/UIComboBox.d.ts.map +1 -1
  41. package/dist/components/UIComboBox/UIComboBox.js +563 -541
  42. package/dist/components/UIComboBox/UIComboBox.js.map +1 -1
  43. package/dist/components/UIComboBox/index.d.ts +1 -1
  44. package/dist/components/UIComboBox/index.js +17 -17
  45. package/dist/components/UIContextualMenu/UIContextualMenu.d.ts +31 -31
  46. package/dist/components/UIContextualMenu/UIContextualMenu.js +126 -126
  47. package/dist/components/UIContextualMenu/UIHighlightMenuOption.d.ts +19 -19
  48. package/dist/components/UIContextualMenu/UIHighlightMenuOption.js +50 -50
  49. package/dist/components/UIContextualMenu/index.d.ts +2 -2
  50. package/dist/components/UIContextualMenu/index.js +18 -18
  51. package/dist/components/UICreateSelect/UICreateSelect.d.ts +36 -36
  52. package/dist/components/UICreateSelect/UICreateSelect.js +172 -172
  53. package/dist/components/UICreateSelect/index.d.ts +1 -1
  54. package/dist/components/UICreateSelect/index.js +17 -17
  55. package/dist/components/UIDatePicker/UIDatePicker.d.ts +49 -49
  56. package/dist/components/UIDatePicker/UIDatePicker.js +72 -72
  57. package/dist/components/UIDatePicker/index.d.ts +1 -1
  58. package/dist/components/UIDatePicker/index.js +17 -17
  59. package/dist/components/UIDialog/UIDialog.d.ts +118 -118
  60. package/dist/components/UIDialog/UIDialog.js +281 -281
  61. package/dist/components/UIDialog/index.d.ts +1 -1
  62. package/dist/components/UIDialog/index.js +17 -17
  63. package/dist/components/UIDropdown/UIDropdown.d.ts +94 -94
  64. package/dist/components/UIDropdown/UIDropdown.js +224 -224
  65. package/dist/components/UIDropdown/index.d.ts +2 -2
  66. package/dist/components/UIDropdown/index.js +18 -18
  67. package/dist/components/UIDropdown/utils.d.ts +20 -20
  68. package/dist/components/UIDropdown/utils.js +43 -43
  69. package/dist/components/UIFlexibleTable/RowActions.d.ts +16 -16
  70. package/dist/components/UIFlexibleTable/RowActions.js +73 -73
  71. package/dist/components/UIFlexibleTable/RowData.d.ts +16 -16
  72. package/dist/components/UIFlexibleTable/RowData.js +111 -111
  73. package/dist/components/UIFlexibleTable/UIFlexibleTable.d.ts +11 -11
  74. package/dist/components/UIFlexibleTable/UIFlexibleTable.js +280 -280
  75. package/dist/components/UIFlexibleTable/UIFlexibleTableActionButton.d.ts +20 -20
  76. package/dist/components/UIFlexibleTable/UIFlexibleTableActionButton.js +20 -20
  77. package/dist/components/UIFlexibleTable/UIFlexibleTableRow.d.ts +26 -26
  78. package/dist/components/UIFlexibleTable/UIFlexibleTableRow.js +219 -219
  79. package/dist/components/UIFlexibleTable/UIFlexibleTableRowActionButton.d.ts +20 -20
  80. package/dist/components/UIFlexibleTable/UIFlexibleTableRowActionButton.js +19 -19
  81. package/dist/components/UIFlexibleTable/UIFlexibleTableRowNoData.d.ts +15 -15
  82. package/dist/components/UIFlexibleTable/UIFlexibleTableRowNoData.js +28 -28
  83. package/dist/components/UIFlexibleTable/index.d.ts +5 -5
  84. package/dist/components/UIFlexibleTable/index.js +21 -21
  85. package/dist/components/UIFlexibleTable/types.d.ts +143 -143
  86. package/dist/components/UIFlexibleTable/types.js +14 -14
  87. package/dist/components/UIFlexibleTable/utils.d.ts +25 -25
  88. package/dist/components/UIFlexibleTable/utils.js +49 -49
  89. package/dist/components/UIFocusZone/UIFocusTrapZone.d.ts +22 -22
  90. package/dist/components/UIFocusZone/UIFocusTrapZone.js +33 -33
  91. package/dist/components/UIFocusZone/UIFocusZone.d.ts +23 -23
  92. package/dist/components/UIFocusZone/UIFocusZone.js +35 -35
  93. package/dist/components/UIFocusZone/index.d.ts +2 -2
  94. package/dist/components/UIFocusZone/index.js +18 -18
  95. package/dist/components/UIIcon/UIIcon.d.ts +24 -24
  96. package/dist/components/UIIcon/UIIcon.js +37 -37
  97. package/dist/components/UIIcon/index.d.ts +1 -1
  98. package/dist/components/UIIcon/index.js +17 -17
  99. package/dist/components/UIInput/UITextInput.d.ts +51 -51
  100. package/dist/components/UIInput/UITextInput.js +244 -244
  101. package/dist/components/UIInput/index.d.ts +1 -1
  102. package/dist/components/UIInput/index.js +17 -17
  103. package/dist/components/UILabel/UILabel.d.ts +30 -30
  104. package/dist/components/UILabel/UILabel.js +64 -64
  105. package/dist/components/UILabel/index.d.ts +1 -1
  106. package/dist/components/UILabel/index.js +17 -17
  107. package/dist/components/UILink/UILink.d.ts +25 -25
  108. package/dist/components/UILink/UILink.js +71 -71
  109. package/dist/components/UILink/index.d.ts +1 -1
  110. package/dist/components/UILink/index.js +17 -17
  111. package/dist/components/UIList/UIList.d.ts +31 -31
  112. package/dist/components/UIList/UIList.js +120 -120
  113. package/dist/components/UIList/index.d.ts +1 -1
  114. package/dist/components/UIList/index.js +17 -17
  115. package/dist/components/UILoader/UILoader.d.ts +27 -27
  116. package/dist/components/UILoader/UILoader.js +78 -78
  117. package/dist/components/UILoader/index.d.ts +1 -1
  118. package/dist/components/UILoader/index.js +17 -17
  119. package/dist/components/UIMessageBar/UIMessageBar.d.ts +25 -25
  120. package/dist/components/UIMessageBar/UIMessageBar.js +56 -56
  121. package/dist/components/UIMessageBar/index.d.ts +1 -1
  122. package/dist/components/UIMessageBar/index.js +17 -17
  123. package/dist/components/UIModal/UIModal.d.ts +23 -23
  124. package/dist/components/UIModal/UIModal.js +43 -43
  125. package/dist/components/UIModal/index.d.ts +1 -1
  126. package/dist/components/UIModal/index.js +17 -17
  127. package/dist/components/UIOverlay/UIOverlay.d.ts +22 -22
  128. package/dist/components/UIOverlay/UIOverlay.js +38 -38
  129. package/dist/components/UIOverlay/index.d.ts +1 -1
  130. package/dist/components/UIOverlay/index.js +17 -17
  131. package/dist/components/UIPersona/UIPersona.d.ts +27 -27
  132. package/dist/components/UIPersona/UIPersona.js +48 -48
  133. package/dist/components/UIPersona/index.d.ts +1 -1
  134. package/dist/components/UIPersona/index.js +17 -17
  135. package/dist/components/UISearchBox/UISearchBox.d.ts +22 -22
  136. package/dist/components/UISearchBox/UISearchBox.js +155 -155
  137. package/dist/components/UISearchBox/index.d.ts +3 -3
  138. package/dist/components/UISearchBox/index.js +17 -17
  139. package/dist/components/UISection/UISection.d.ts +34 -34
  140. package/dist/components/UISection/UISection.js +44 -44
  141. package/dist/components/UISection/UISections.d.ts +249 -249
  142. package/dist/components/UISection/UISections.js +707 -707
  143. package/dist/components/UISection/UISplitter.d.ts +96 -96
  144. package/dist/components/UISection/UISplitter.js +220 -220
  145. package/dist/components/UISection/index.d.ts +3 -3
  146. package/dist/components/UISection/index.js +19 -19
  147. package/dist/components/UISeparator/UISeparator.d.ts +25 -25
  148. package/dist/components/UISeparator/UISeparator.js +65 -65
  149. package/dist/components/UISeparator/index.d.ts +1 -1
  150. package/dist/components/UISeparator/index.js +17 -17
  151. package/dist/components/UITable/UITable-helper.d.ts +88 -88
  152. package/dist/components/UITable/UITable-helper.js +263 -263
  153. package/dist/components/UITable/UITable.d.ts +213 -213
  154. package/dist/components/UITable/UITable.js +779 -779
  155. package/dist/components/UITable/index.d.ts +2 -2
  156. package/dist/components/UITable/index.js +18 -18
  157. package/dist/components/UITable/types.d.ts +77 -77
  158. package/dist/components/UITable/types.js +28 -28
  159. package/dist/components/UITabs/UITabs.d.ts +28 -28
  160. package/dist/components/UITabs/UITabs.js +70 -70
  161. package/dist/components/UITabs/index.d.ts +1 -1
  162. package/dist/components/UITabs/index.js +17 -17
  163. package/dist/components/UIToggle/UIToggle.d.ts +39 -39
  164. package/dist/components/UIToggle/UIToggle.js +181 -181
  165. package/dist/components/UIToggle/index.d.ts +1 -1
  166. package/dist/components/UIToggle/index.js +17 -17
  167. package/dist/components/UIToggleGroup/UIToggleGroup.d.ts +31 -31
  168. package/dist/components/UIToggleGroup/UIToggleGroup.js +139 -139
  169. package/dist/components/UIToggleGroup/UIToggleGroup.types.d.ts +22 -22
  170. package/dist/components/UIToggleGroup/UIToggleGroup.types.js +2 -2
  171. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.d.ts +25 -25
  172. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.js +77 -77
  173. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.types.d.ts +10 -10
  174. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.types.js +2 -2
  175. package/dist/components/UIToggleGroup/UIToggleGroupOption/index.d.ts +2 -2
  176. package/dist/components/UIToggleGroup/UIToggleGroupOption/index.js +18 -18
  177. package/dist/components/UIToggleGroup/index.d.ts +2 -2
  178. package/dist/components/UIToggleGroup/index.js +18 -18
  179. package/dist/components/UIToolbar/UIToolbar.d.ts +36 -36
  180. package/dist/components/UIToolbar/UIToolbar.js +104 -104
  181. package/dist/components/UIToolbar/UIToolbarColumn.d.ts +7 -7
  182. package/dist/components/UIToolbar/UIToolbarColumn.js +33 -33
  183. package/dist/components/UIToolbar/UIToolbarDivider.d.ts +27 -27
  184. package/dist/components/UIToolbar/UIToolbarDivider.js +52 -52
  185. package/dist/components/UIToolbar/index.d.ts +3 -3
  186. package/dist/components/UIToolbar/index.js +19 -19
  187. package/dist/components/UITooltip/UITooltip.d.ts +29 -29
  188. package/dist/components/UITooltip/UITooltip.js +77 -77
  189. package/dist/components/UITooltip/UITooltipUtils.d.ts +17 -17
  190. package/dist/components/UITooltip/UITooltipUtils.js +45 -45
  191. package/dist/components/UITooltip/index.d.ts +2 -2
  192. package/dist/components/UITooltip/index.js +18 -18
  193. package/dist/components/UITranslationInput/UIFormattedText.d.ts +46 -46
  194. package/dist/components/UITranslationInput/UIFormattedText.js +121 -121
  195. package/dist/components/UITranslationInput/UILoadButton.d.ts +52 -52
  196. package/dist/components/UITranslationInput/UILoadButton.js +109 -109
  197. package/dist/components/UITranslationInput/UITranslationButton.d.ts +14 -14
  198. package/dist/components/UITranslationInput/UITranslationButton.js +88 -88
  199. package/dist/components/UITranslationInput/UITranslationButton.types.d.ts +67 -67
  200. package/dist/components/UITranslationInput/UITranslationButton.types.js +21 -21
  201. package/dist/components/UITranslationInput/UITranslationInput.d.ts +25 -25
  202. package/dist/components/UITranslationInput/UITranslationInput.js +169 -169
  203. package/dist/components/UITranslationInput/UITranslationUtils.d.ts +64 -64
  204. package/dist/components/UITranslationInput/UITranslationUtils.js +168 -168
  205. package/dist/components/UITranslationInput/defaults.d.ts +2 -2
  206. package/dist/components/UITranslationInput/defaults.js +15 -15
  207. package/dist/components/UITranslationInput/index.d.ts +2 -2
  208. package/dist/components/UITranslationInput/index.js +18 -18
  209. package/dist/components/UITreeDropdown/UITreeDropdown.d.ts +265 -265
  210. package/dist/components/UITreeDropdown/UITreeDropdown.js +660 -660
  211. package/dist/components/UITreeDropdown/index.d.ts +1 -1
  212. package/dist/components/UITreeDropdown/index.js +17 -17
  213. package/dist/components/UIVerticalDivider/UIVerticalDivider.d.ts +23 -23
  214. package/dist/components/UIVerticalDivider/UIVerticalDivider.js +41 -41
  215. package/dist/components/UIVerticalDivider/index.d.ts +1 -1
  216. package/dist/components/UIVerticalDivider/index.js +17 -17
  217. package/dist/components/UIVirtualList/UIAutoSizer.d.ts +22 -22
  218. package/dist/components/UIVirtualList/UIAutoSizer.js +33 -33
  219. package/dist/components/UIVirtualList/UICellMeasurer.d.ts +23 -23
  220. package/dist/components/UIVirtualList/UICellMeasurer.js +33 -33
  221. package/dist/components/UIVirtualList/UIVirtualList.d.ts +43 -43
  222. package/dist/components/UIVirtualList/UIVirtualList.js +70 -70
  223. package/dist/components/UIVirtualList/index.d.ts +3 -3
  224. package/dist/components/UIVirtualList/index.js +19 -19
  225. package/dist/components/index.d.ts +38 -38
  226. package/dist/components/index.js +54 -54
  227. package/dist/helper/ValidationMessage/MessageWrapper.d.ts +17 -17
  228. package/dist/helper/ValidationMessage/MessageWrapper.js +34 -34
  229. package/dist/helper/ValidationMessage/index.d.ts +2 -2
  230. package/dist/helper/ValidationMessage/index.js +18 -18
  231. package/dist/helper/ValidationMessage/utils.d.ts +31 -31
  232. package/dist/helper/ValidationMessage/utils.js +121 -121
  233. package/dist/index.d.ts +2 -2
  234. package/dist/index.js +18 -18
  235. package/dist/utilities/DeepMerge.d.ts +10 -10
  236. package/dist/utilities/DeepMerge.js +48 -48
  237. package/dist/utilities/Dom.d.ts +14 -7
  238. package/dist/utilities/Dom.d.ts.map +1 -1
  239. package/dist/utilities/Dom.js +23 -13
  240. package/dist/utilities/Dom.js.map +1 -1
  241. package/dist/utilities/Focus.d.ts +14 -14
  242. package/dist/utilities/Focus.js +34 -34
  243. package/dist/utilities/Id.d.ts +2 -2
  244. package/dist/utilities/Id.js +5 -5
  245. package/dist/utilities/Keys.d.ts +2 -2
  246. package/dist/utilities/Keys.js +5 -5
  247. package/dist/utilities/index.d.ts +4 -4
  248. package/dist/utilities/index.js +20 -20
  249. package/package.json +1 -1
  250. package/storybook/494.d8aaa4d7.iframe.bundle.js +1 -0
  251. package/storybook/580.057c85e9.iframe.bundle.js +1 -0
  252. package/storybook/{930.1b3c5615.iframe.bundle.js → 930.3177b0dc.iframe.bundle.js} +2 -2
  253. package/storybook/UIActionCallout-story.9ee56c83.iframe.bundle.js +2 -0
  254. package/storybook/UIToggleGroup-story.573848ba.iframe.bundle.js +2 -0
  255. package/storybook/iframe.html +3 -3
  256. package/storybook/main.5f68bcca.iframe.bundle.js +1 -0
  257. package/storybook/project.json +1 -1
  258. package/storybook/{runtime~main.7c93d414.iframe.bundle.js → runtime~main.a213c0ae.iframe.bundle.js} +1 -1
  259. package/storybook/494.1829058d.iframe.bundle.js +0 -1
  260. package/storybook/580.c5ddde6e.iframe.bundle.js +0 -1
  261. package/storybook/UIActionCallout-story.13bdf055.iframe.bundle.js +0 -2
  262. package/storybook/UIToggleGroup-story.6f3e7d06.iframe.bundle.js +0 -2
  263. package/storybook/main.4ed99289.iframe.bundle.js +0 -1
@@ -1,542 +1,564 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.UIComboBox = exports.UISelectableOptionMenuItemType = void 0;
7
- const react_1 = __importDefault(require("react"));
8
- const react_2 = require("@fluentui/react");
9
- Object.defineProperty(exports, "UISelectableOptionMenuItemType", { enumerable: true, get: function () { return react_2.SelectableOptionMenuItemType; } });
10
- const UIHighlightMenuOption_1 = require("../UIContextualMenu/UIHighlightMenuOption");
11
- require("./UIComboBox.scss");
12
- require("./Callout.scss");
13
- const UILoader_1 = require("../UILoader");
14
- const Icons_1 = require("../Icons");
15
- const ValidationMessage_1 = require("../../helper/ValidationMessage");
16
- const UILabel_1 = require("../UILabel");
17
- const UIDropdown_1 = require("../UIDropdown");
18
- const UICallout_1 = require("../UICallout");
19
- /**
20
- * UIComboBox component.
21
- *
22
- * @exports
23
- * @class {UIComboBox}
24
- * @extends {React.Component<UIComboBoxProps, UIComboBoxState>}
25
- */
26
- class UIComboBox extends react_1.default.Component {
27
- /**
28
- * Initializes component properties.
29
- *
30
- * @param {UIComboBoxProps} props
31
- */
32
- constructor(props) {
33
- super(props);
34
- // Reference to fluent ui combobox
35
- this.comboBox = react_1.default.createRef();
36
- this.comboboxDomRef = react_1.default.createRef();
37
- this.menuDomRef = react_1.default.createRef();
38
- this.selectedElement = react_1.default.createRef();
39
- this.query = '';
40
- this.ignoreOpenKeys = ['Meta', 'Control', 'Shift', 'Tab', 'Alt', 'CapsLock'];
41
- this.isListHidden = false;
42
- this.calloutCollisionTransform = new UICallout_1.CalloutCollisionTransform(this.comboboxDomRef, this.menuDomRef);
43
- /**
44
- * Method called on combobox option resolvation.
45
- * We should not allow to add any custom option.
46
- *
47
- * @returns {IComboBoxOption[]} Array of combobox items.
48
- */
49
- this.onResolveOptions = () => {
50
- return this.props.options;
51
- };
52
- /**
53
- * Method called on combobox item render.
54
- * We should pass query to it and avoid rendering if it is hidden.
55
- *
56
- * @param {IComboBoxOption} props Combobox item props.
57
- * @param {Function} defaultRender Combobox item default renderer.
58
- * @returns {JSX.Element | null} Element to render.
59
- */
60
- this.onRenderItem = (props, defaultRender) => {
61
- if (defaultRender && props) {
62
- // Use data for custom onRender functions
63
- props.data = this.query;
64
- if (props.title === undefined) {
65
- // Apply title by default if property not provided
66
- // In older fluent-ui versions it was applied by default, but behavior changed in version '8.66.2'
67
- props.title = props.text;
68
- }
69
- const selected = props.index !== undefined && this.getCurrentSelectedIndex() === props.index;
70
- return !props.hidden ? (react_1.default.createElement("div", { key: props.key, ref: selected ? this.selectedElement : undefined, className: `${selected ? 'ts-ComboBox--selected' : ''}` }, defaultRender(props))) : null;
71
- }
72
- return null;
73
- };
74
- /**
75
- * Method to get current selected index.
76
- *
77
- * @returns {number | undefined} Selected item index.
78
- */
79
- this.getCurrentSelectedIndex = () => {
80
- const baseCombobox = this.comboBox.current;
81
- if (!baseCombobox) {
82
- return undefined;
83
- }
84
- if (baseCombobox.state.currentPendingValueValidIndex !== -1) {
85
- return baseCombobox.state.currentPendingValueValidIndex;
86
- }
87
- return baseCombobox.props.hoisted.selectedIndices ? baseCombobox.props.hoisted.selectedIndices[0] : undefined;
88
- };
89
- /**
90
- * Return a value for the placeholder.
91
- *
92
- * @returns {string}
93
- */
94
- this.getPlaceholder = () => {
95
- if (this.props.placeholder) {
96
- return this.props.placeholder;
97
- }
98
- else {
99
- // That string should be translated
100
- return 'Search or select from dropdown';
101
- }
102
- };
103
- /**
104
- * Method called on combobox item's option/label render.
105
- * We should use different componenet which support highlighting - 'ComboboxSearchOption'.
106
- *
107
- * @param {IComboBoxOption} props Combobox item props.
108
- * @param {Function} defaultRender Combobox item default renderer.
109
- * @returns {JSX.Element | null} Element to render.
110
- */
111
- this.onRenderOption = (props, defaultRender) => {
112
- if (props && props.itemType !== react_2.SelectableOptionMenuItemType.Header) {
113
- return react_1.default.createElement(UIHighlightMenuOption_1.UIHighlightMenuOption, { text: props.text, query: this.query });
114
- }
115
- return defaultRender ? defaultRender(props) : null;
116
- };
117
- this.handleChange = (event, option) => {
118
- if (option && this.props.onHandleChange) {
119
- this.props.onHandleChange(option.key);
120
- }
121
- };
122
- this.onRenderListLoading = () => {
123
- const styles = {
124
- label: {
125
- fontSize: '11px',
126
- fontWeight: 'normal'
127
- }
128
- };
129
- return (react_1.default.createElement("div", { className: "option-loading" },
130
- react_1.default.createElement(UILoader_1.UILoader, { label: "Loading", className: "uiLoaderXSmall", labelPosition: "right", styles: styles })));
131
- };
132
- this.onInput = this.onInput.bind(this);
133
- this.reserQuery = this.reserQuery.bind(this);
134
- this.onResolveOptions = this.onResolveOptions.bind(this);
135
- this.onRenderItem = this.onRenderItem.bind(this);
136
- this.onRenderOption = this.onRenderOption.bind(this);
137
- this.onKeyDown = this.onKeyDown.bind(this);
138
- this.onClick = this.onClick.bind(this);
139
- this.handleRefreshButton = this.handleRefreshButton.bind(this);
140
- this.onPendingValueChanged = this.onPendingValueChanged.bind(this);
141
- this.onMultiSelectChange = this.onMultiSelectChange.bind(this);
142
- this.onScrollToItem = this.onScrollToItem.bind(this);
143
- this.setFocus = this.setFocus.bind(this);
144
- (0, react_2.initializeComponentRef)(this);
145
- this.state = {};
146
- }
147
- /**
148
- *
149
- * @param {UIComboBoxProps} nextProps
150
- * @returns {boolean}
151
- */
152
- shouldComponentUpdate(nextProps) {
153
- if (nextProps.options !== this.props.options && this.query) {
154
- // Filter options
155
- this.updateHiddenOptions(nextProps.options);
156
- }
157
- return true;
158
- }
159
- /**
160
- * Updates hidden options.
161
- *
162
- * @param {IComboBoxOption[]} opts
163
- */
164
- updateHiddenOptions(opts) {
165
- this.isListHidden = true;
166
- let currentGroup;
167
- let isGroupVisible = false;
168
- const updateGroupVisibility = () => {
169
- if (currentGroup) {
170
- currentGroup.hidden = !isGroupVisible;
171
- }
172
- };
173
- for (const option of opts) {
174
- if (option.itemType === react_2.SelectableOptionMenuItemType.Header) {
175
- // Update visibility of previously processed group
176
- updateGroupVisibility();
177
- // Reset current group and visibility flag
178
- currentGroup = option;
179
- isGroupVisible = false;
180
- }
181
- else {
182
- // Handle selectable item
183
- const isHidden = option.text.toLowerCase().indexOf(this.query) === -1;
184
- option.hidden = isHidden;
185
- if (this.isListHidden && !option.hidden) {
186
- this.isListHidden = false;
187
- }
188
- // Groups should be visible if at least one item is visible within group
189
- isGroupVisible = !isHidden || isGroupVisible;
190
- }
191
- }
192
- updateGroupVisibility();
193
- }
194
- /**
195
- * Method filters options and hides unmatched options.
196
- *
197
- * @param {React.FormEvent<IComboBox>} event Combobox event object
198
- */
199
- onInput(event) {
200
- this.isListHidden = false;
201
- if (event.target) {
202
- const input = event.target;
203
- this.query = input.value.trimStart().toLowerCase();
204
- // Filter options
205
- const baseCombobox = this.comboBox.current;
206
- if (baseCombobox) {
207
- this.updateHiddenOptions(baseCombobox.props.hoisted.currentOptions);
208
- }
209
- }
210
- }
211
- /**
212
- * Method opens menu when user clicks on Combobox (input or button).
213
- */
214
- onClick() {
215
- const baseCombobox = this.comboBox.current;
216
- const isOpen = baseCombobox && baseCombobox.state.isOpen;
217
- const isDisabled = this.props.disabled;
218
- if (this.props.openMenuOnClick && baseCombobox && !isOpen && !isDisabled) {
219
- baseCombobox.focus(true);
220
- }
221
- }
222
- /**
223
- * Method handles keydown event and does following.
224
- * 1. Fix for bug(in fluentui sources) regarding keyboard navigation when last item is not visible.
225
- * 2. Opens list when user enters any key.
226
- *
227
- * @param {React.FormEvent<HTMLInputElement>} event Keydown event
228
- */
229
- onKeyDown(event) {
230
- let handled = false;
231
- const baseCombobox = this.comboBox.current;
232
- const isOpen = baseCombobox && baseCombobox.state.isOpen;
233
- if (event.which === react_2.KeyCodes.down || event.which === react_2.KeyCodes.up) {
234
- handled = this._setCyclingNavigation(event.which === react_2.KeyCodes.down);
235
- }
236
- if (handled) {
237
- // Do not handle keydown of combobox
238
- event.preventDefault();
239
- event.stopPropagation();
240
- }
241
- else if (!this.ignoreOpenKeys.includes(event.key) && baseCombobox && !isOpen) {
242
- // Open dropdown list on first key press instead of showing it right after focus
243
- baseCombobox.focus(true);
244
- }
245
- }
246
- /**
247
- * Method resets search query.
248
- */
249
- reserQuery() {
250
- this.query = '';
251
- for (const option of this.props.options) {
252
- delete option.hidden;
253
- }
254
- this.isListHidden = false;
255
- this.setState({
256
- isListHidden: this.isListHidden
257
- });
258
- }
259
- /**
260
- * Method which determines what is next visible item - it is used to fix bug in fluentui sources..
261
- *
262
- * @param {number} index Current index.
263
- * @param {boolean} forward Dirrection to look up.
264
- * @returns {ComboboxItemInfo | null} Combobox item object.
265
- */
266
- getNextVisibleItem(index, forward) {
267
- const limit = this.props.options.length;
268
- while (index >= 0 && index < limit) {
269
- if (this.props.options[index] && !this.props.options[index].hidden) {
270
- return {
271
- option: this.props.options[index],
272
- index
273
- };
274
- }
275
- index = index + (forward ? 1 : -1);
276
- }
277
- return null;
278
- }
279
- /**
280
- * Method is used as fix for bug(in fluentui sources) regarding keyboard navigation when last item is not visible.
281
- *
282
- * @param {boolean} forward Dirrection to look up.
283
- * @returns {boolean} Returs true if method changed navigation.
284
- */
285
- _setCyclingNavigation(forward) {
286
- const baseCombobox = this.comboBox.current;
287
- if (baseCombobox && baseCombobox.state.currentPendingValueValidIndex >= 0) {
288
- // Check if there exists any visible item in that direction
289
- let index = baseCombobox.state.currentPendingValueValidIndex;
290
- const limit = this.props.options.length - 1;
291
- index = index + (forward ? 1 : -1);
292
- let option = this.getNextVisibleItem(index, forward);
293
- if (option) {
294
- // Item exists - no need for custom logic as we are fixing issue in base control
295
- return false;
296
- }
297
- // Item was not found - make circular navigation
298
- option = this.getNextVisibleItem(forward ? 0 : limit, forward);
299
- if (option) {
300
- // We fixed issue in base combobox control -
301
- // when last item is not visible and we navigate it
302
- baseCombobox.setState({
303
- currentPendingValueValidIndex: option.index,
304
- currentPendingValue: option.option.text
305
- });
306
- return true;
307
- }
308
- }
309
- return false;
310
- }
311
- /**
312
- * Method for property 'useComboBoxAsMenuMinWidth' - method resolves current dropdown width and updates state with latest value.
313
- * 'minWidth' from state is used to set callout size in render.
314
- */
315
- calculateMenuMinWidth() {
316
- const comboBoxWrapper = this.comboBox.current?._comboBoxWrapper.current;
317
- if (comboBoxWrapper &&
318
- this.props.useComboBoxAsMenuMinWidth &&
319
- comboBoxWrapper.clientWidth !== this.state.minWidth) {
320
- this.setState({
321
- minWidth: comboBoxWrapper.clientWidth
322
- });
323
- }
324
- }
325
- /**
326
- * Method called only when property 'highlight' is true.
327
- * Method called after each value live change - we need recheck if there is any visible item after search is done.
328
- * 1. If there no any visible item - we hide menu callout.
329
- * 2. If there is any visible item - we show menu callout.
330
- *
331
- * @param option Selected option.
332
- * @param index Selected option's index.
333
- * @param value Text value entered in input.
334
- */
335
- onPendingValueChanged(option, index, value) {
336
- if (this.state.isListHidden !== this.isListHidden) {
337
- this.setState({
338
- isListHidden: this.isListHidden
339
- });
340
- }
341
- if (this.props?.onPendingValueChanged) {
342
- this.props?.onPendingValueChanged(option, index, value);
343
- }
344
- }
345
- /**
346
- * Public method to close menu callout if it is open.
347
- */
348
- dismissMenu() {
349
- if (this.comboBox.current) {
350
- this.comboBox.current.dismissMenu();
351
- }
352
- }
353
- /**
354
- * Public method to set the focus on the combo box.
355
- */
356
- setFocus() {
357
- if (this.comboBox.current) {
358
- this.comboBox.current.focus();
359
- }
360
- }
361
- /**
362
- * Method called only when property 'onRefresh' has been defined.
363
- * It is called when click on the refresh buttonIcon.
364
- */
365
- handleRefreshButton() {
366
- const baseCombobox = this.comboBox.current;
367
- if (this.props.useComboBoxAsMenuMinWidth) {
368
- this.calculateMenuMinWidth();
369
- }
370
- if (this.props.onRefresh) {
371
- this.props.onRefresh();
372
- baseCombobox?.focus(true);
373
- }
374
- }
375
- /**
376
- * Handle multiselect change by avoiding 'blur' event.
377
- * Problem is that blur event uses suggested value and toggles selection for it.
378
- *
379
- * @param {React.FormEvent<IComboBox>} event on change
380
- * @param {IComboBoxOption} option changed option
381
- * @param {number} index option index
382
- * @param {string} value changed value
383
- */
384
- onMultiSelectChange(event, option, index, value) {
385
- // Ignore toggle if change triggered by blur
386
- if (this.props.onChange && event.type !== 'blur') {
387
- this.props.onChange(event, option, index, value);
388
- }
389
- }
390
- /**
391
- * Method is used to fix bug in fluent ui.
392
- * Bug is for multiselect combobox - when keyboard navigation is used, then scrollbar position is not updated to make selected option visible in viewport.
393
- */
394
- onScrollToItem() {
395
- // Multi select only
396
- const selectedElement = this.selectedElement.current;
397
- if (!this.props.multiSelect || !selectedElement) {
398
- return;
399
- }
400
- const offsetParent = selectedElement.offsetParent;
401
- if (offsetParent) {
402
- const size = offsetParent.clientHeight;
403
- const scrollSize = offsetParent.scrollHeight;
404
- if (scrollSize > size) {
405
- const elementTop = selectedElement.offsetTop;
406
- const elementBottom = elementTop + selectedElement.clientHeight;
407
- const scrollTop = offsetParent.scrollTop;
408
- const scrollBottom = scrollTop + size;
409
- if (!(elementTop >= scrollTop && elementBottom <= scrollBottom)) {
410
- // Outline node is not visible in viewport
411
- const diff = elementBottom > scrollBottom ? elementBottom - scrollBottom : elementTop - scrollTop;
412
- offsetParent.scrollTop = scrollTop + diff;
413
- }
414
- }
415
- }
416
- }
417
- /**
418
- * Method returns class names string depending on props and component state.
419
- *
420
- * @param {InputValidationMessageInfo} messageInfo Error/warning message if applied
421
- * @returns {string} Class names of root combobox element.
422
- */
423
- getClassNames(messageInfo) {
424
- const { readOnly, disabled } = this.props;
425
- const errorSuffix = messageInfo.message ? ValidationMessage_1.MESSAGE_TYPES_CLASSNAME_MAP.get(messageInfo.type) : undefined;
426
- let classNames = `ts-ComboBox${messageInfo.message ? ' ts-ComboBox--' + errorSuffix : ''}`;
427
- if (readOnly && !disabled) {
428
- classNames += ' ts-ComboBox--readonly';
429
- }
430
- if (disabled) {
431
- classNames += ' ts-ComboBox--disabled';
432
- }
433
- if ((0, UIDropdown_1.isDropdownEmpty)(this.props)) {
434
- classNames += ' ts-ComboBox--empty';
435
- }
436
- return classNames;
437
- }
438
- /**
439
- * Method returns properties for Autofill component(combobox's inner compnent for text input).
440
- * Method handles 'highlight' and 'readOnly' properties.
441
- *
442
- * @returns {IAutofillProps} Properties for Autofill component.
443
- */
444
- getAutofillProps() {
445
- const { highlight, readOnly, disabled } = this.props;
446
- const autofill = {};
447
- // Handle search highligh
448
- if (highlight) {
449
- autofill.onKeyDownCapture = this.onKeyDown;
450
- }
451
- const tabIndex = 'tabIndex' in this.props ? this.props.tabIndex : undefined;
452
- // Handle readOnly property
453
- if (readOnly && !disabled) {
454
- autofill.readOnly = readOnly;
455
- autofill.tabIndex = tabIndex;
456
- // Adjust aria attributes for readonly
457
- autofill['aria-disabled'] = undefined;
458
- autofill['aria-readonly'] = true;
459
- }
460
- else if (disabled) {
461
- autofill.disabled = undefined;
462
- autofill.readOnly = true;
463
- autofill.tabIndex = tabIndex;
464
- }
465
- return autofill;
466
- }
467
- /**
468
- * @returns {JSX.Element}
469
- */
470
- render() {
471
- const messageInfo = (0, ValidationMessage_1.getMessageInfo)(this.props);
472
- let disabled = this.props.isForceEnabled ? false : !this.props.options.length;
473
- if (this.props.readOnly) {
474
- disabled = true;
475
- }
476
- return (react_1.default.createElement("div", { ref: this.props.wrapperRef, className: this.getClassNames(messageInfo) },
477
- react_1.default.createElement(react_2.ComboBox, { componentRef: this.comboBox, ref: this.comboboxDomRef, disabled: disabled, iconButtonProps: {
478
- iconProps: {
479
- iconName: Icons_1.UiIcons.ArrowDown
480
- }
481
- }, calloutProps: {
482
- calloutMaxHeight: 200,
483
- popupProps: {
484
- ref: this.menuDomRef
485
- },
486
- className: 'ts-Callout ts-Callout-Dropdown',
487
- styles: {
488
- ...(this.props.useComboBoxAsMenuMinWidth && {
489
- calloutMain: {
490
- minWidth: this.state.minWidth,
491
- display: this.state.isListHidden ? 'none' : undefined
492
- }
493
- })
494
- },
495
- ...(0, UIDropdown_1.getCalloutCollisionTransformationProps)(this.calloutCollisionTransform, this.props.multiSelect, this.props.calloutCollisionTransformation)
496
- }, styles: {
497
- label: {
498
- ...UILabel_1.labelGlobalStyle,
499
- ...(this.props.disabled && {
500
- opacity: '0.4'
501
- }),
502
- ...(this.props.required && {
503
- selectors: {
504
- '::after': {
505
- content: `' *'`,
506
- color: 'var(--vscode-inputValidation-errorBorder)',
507
- paddingRight: 12
508
- }
509
- }
510
- })
511
- },
512
- errorMessage: [messageInfo.style]
513
- }, ...this.props, ...(this.props.highlight && {
514
- onInput: this.onInput,
515
- onMenuDismissed: this.reserQuery,
516
- onResolveOptions: this.onResolveOptions,
517
- onRenderItem: this.onRenderItem,
518
- onRenderOption: this.onRenderOption,
519
- placeholder: this.getPlaceholder(),
520
- onPendingValueChanged: this.onPendingValueChanged
521
- }), autofill: this.getAutofillProps(), ...(this.props.useComboBoxAsMenuMinWidth && {
522
- // Use 'onMenuOpen', because there can be dynamic size of combobox
523
- onMenuOpen: this.calculateMenuMinWidth.bind(this)
524
- }), ...(this.props.openMenuOnClick && {
525
- onClick: this.onClick.bind(this)
526
- }), ...(this.props.onRefresh && {
527
- onMenuOpen: this.handleRefreshButton,
528
- onChange: this.handleChange
529
- }), ...(this.props.isLoading && {
530
- onRenderList: this.onRenderListLoading
531
- }), ...(this.props.multiSelect && {
532
- onScrollToItem: this.onScrollToItem,
533
- ...(this.props.onChange && {
534
- onChange: this.onMultiSelectChange
535
- })
536
- }), errorMessage: messageInfo.message })));
537
- }
538
- }
539
- exports.UIComboBox = UIComboBox;
540
- // Default values for public component properties
541
- UIComboBox.defaultProps = { openMenuOnClick: true };
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UIComboBox = exports.UISelectableOptionMenuItemType = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_2 = require("@fluentui/react");
9
+ Object.defineProperty(exports, "UISelectableOptionMenuItemType", { enumerable: true, get: function () { return react_2.SelectableOptionMenuItemType; } });
10
+ const UIHighlightMenuOption_1 = require("../UIContextualMenu/UIHighlightMenuOption");
11
+ require("./UIComboBox.scss");
12
+ require("./Callout.scss");
13
+ const UILoader_1 = require("../UILoader");
14
+ const Icons_1 = require("../Icons");
15
+ const ValidationMessage_1 = require("../../helper/ValidationMessage");
16
+ const UILabel_1 = require("../UILabel");
17
+ const UIDropdown_1 = require("../UIDropdown");
18
+ const UICallout_1 = require("../UICallout");
19
+ const utilities_1 = require("../../utilities");
20
+ /**
21
+ * UIComboBox component.
22
+ *
23
+ * @exports
24
+ * @class {UIComboBox}
25
+ * @extends {React.Component<UIComboBoxProps, UIComboBoxState>}
26
+ */
27
+ class UIComboBox extends react_1.default.Component {
28
+ /**
29
+ * Initializes component properties.
30
+ *
31
+ * @param {UIComboBoxProps} props
32
+ */
33
+ constructor(props) {
34
+ super(props);
35
+ // Reference to fluent ui combobox
36
+ this.comboBox = react_1.default.createRef();
37
+ this.comboboxDomRef = react_1.default.createRef();
38
+ this.menuDomRef = react_1.default.createRef();
39
+ this.selectedElement = react_1.default.createRef();
40
+ this.query = '';
41
+ this.ignoreOpenKeys = ['Meta', 'Control', 'Shift', 'Tab', 'Alt', 'CapsLock'];
42
+ this.isListHidden = false;
43
+ this.calloutCollisionTransform = new UICallout_1.CalloutCollisionTransform(this.comboboxDomRef, this.menuDomRef);
44
+ /**
45
+ * Method called on combobox option resolvation.
46
+ * We should not allow to add any custom option.
47
+ *
48
+ * @returns {IComboBoxOption[]} Array of combobox items.
49
+ */
50
+ this.onResolveOptions = () => {
51
+ return this.props.options;
52
+ };
53
+ /**
54
+ * Method called on combobox item render.
55
+ * We should pass query to it and avoid rendering if it is hidden.
56
+ *
57
+ * @param {IComboBoxOption} props Combobox item props.
58
+ * @param {Function} defaultRender Combobox item default renderer.
59
+ * @returns {JSX.Element | null} Element to render.
60
+ */
61
+ this.onRenderItem = (props, defaultRender) => {
62
+ if (defaultRender && props) {
63
+ // Use data for custom onRender functions
64
+ props.data = this.query;
65
+ if (props.title === undefined) {
66
+ // Apply title by default if property not provided
67
+ // In older fluent-ui versions it was applied by default, but behavior changed in version '8.66.2'
68
+ props.title = props.text;
69
+ }
70
+ const selected = props.index !== undefined && this.getCurrentSelectedIndex() === props.index;
71
+ return !props.hidden ? (react_1.default.createElement("div", { key: props.key, ref: selected ? this.selectedElement : undefined, className: `${selected ? 'ts-ComboBox--selected' : ''}` }, defaultRender(props))) : null;
72
+ }
73
+ return null;
74
+ };
75
+ /**
76
+ * Method to get current selected index.
77
+ *
78
+ * @returns {number | undefined} Selected item index.
79
+ */
80
+ this.getCurrentSelectedIndex = () => {
81
+ const baseCombobox = this.comboBox.current;
82
+ if (!baseCombobox) {
83
+ return undefined;
84
+ }
85
+ if (baseCombobox.state.currentPendingValueValidIndex !== -1) {
86
+ return baseCombobox.state.currentPendingValueValidIndex;
87
+ }
88
+ return baseCombobox.props.hoisted.selectedIndices ? baseCombobox.props.hoisted.selectedIndices[0] : undefined;
89
+ };
90
+ /**
91
+ * Return a value for the placeholder.
92
+ *
93
+ * @returns {string}
94
+ */
95
+ this.getPlaceholder = () => {
96
+ if (this.props.placeholder) {
97
+ return this.props.placeholder;
98
+ }
99
+ else {
100
+ // That string should be translated
101
+ return 'Search or select from dropdown';
102
+ }
103
+ };
104
+ /**
105
+ * Method called on combobox item's option/label render.
106
+ * We should use different componenet which support highlighting - 'ComboboxSearchOption'.
107
+ *
108
+ * @param {IComboBoxOption} props Combobox item props.
109
+ * @param {Function} defaultRender Combobox item default renderer.
110
+ * @returns {JSX.Element | null} Element to render.
111
+ */
112
+ this.onRenderOption = (props, defaultRender) => {
113
+ if (props && props.itemType !== react_2.SelectableOptionMenuItemType.Header) {
114
+ return react_1.default.createElement(UIHighlightMenuOption_1.UIHighlightMenuOption, { text: props.text, query: this.query });
115
+ }
116
+ return defaultRender ? defaultRender(props) : null;
117
+ };
118
+ this.handleChange = (event, option) => {
119
+ if (option && this.props.onHandleChange) {
120
+ this.props.onHandleChange(option.key);
121
+ }
122
+ };
123
+ this.onRenderListLoading = () => {
124
+ const styles = {
125
+ label: {
126
+ fontSize: '11px',
127
+ fontWeight: 'normal'
128
+ }
129
+ };
130
+ return (react_1.default.createElement("div", { className: "option-loading" },
131
+ react_1.default.createElement(UILoader_1.UILoader, { label: "Loading", className: "uiLoaderXSmall", labelPosition: "right", styles: styles })));
132
+ };
133
+ this.onInput = this.onInput.bind(this);
134
+ this.reserQuery = this.reserQuery.bind(this);
135
+ this.onResolveOptions = this.onResolveOptions.bind(this);
136
+ this.onRenderItem = this.onRenderItem.bind(this);
137
+ this.onRenderOption = this.onRenderOption.bind(this);
138
+ this.onKeyDown = this.onKeyDown.bind(this);
139
+ this.onClick = this.onClick.bind(this);
140
+ this.handleRefreshButton = this.handleRefreshButton.bind(this);
141
+ this.onPendingValueChanged = this.onPendingValueChanged.bind(this);
142
+ this.onMultiSelectChange = this.onMultiSelectChange.bind(this);
143
+ this.onScrollToItem = this.onScrollToItem.bind(this);
144
+ this.setFocus = this.setFocus.bind(this);
145
+ (0, react_2.initializeComponentRef)(this);
146
+ this.state = {};
147
+ }
148
+ /**
149
+ *
150
+ * @param {UIComboBoxProps} nextProps
151
+ * @returns {boolean}
152
+ */
153
+ shouldComponentUpdate(nextProps) {
154
+ if (nextProps.options !== this.props.options && this.query) {
155
+ // Filter options
156
+ this.updateHiddenOptions(nextProps.options);
157
+ }
158
+ return true;
159
+ }
160
+ /**
161
+ * Updates hidden options.
162
+ *
163
+ * @param {IComboBoxOption[]} opts
164
+ */
165
+ updateHiddenOptions(opts) {
166
+ this.isListHidden = true;
167
+ let currentGroup;
168
+ let isGroupVisible = false;
169
+ const updateGroupVisibility = () => {
170
+ if (currentGroup) {
171
+ currentGroup.hidden = !isGroupVisible;
172
+ }
173
+ };
174
+ for (const option of opts) {
175
+ if (option.itemType === react_2.SelectableOptionMenuItemType.Header) {
176
+ // Update visibility of previously processed group
177
+ updateGroupVisibility();
178
+ // Reset current group and visibility flag
179
+ currentGroup = option;
180
+ isGroupVisible = false;
181
+ }
182
+ else {
183
+ // Handle selectable item
184
+ const isHidden = option.text.toLowerCase().indexOf(this.query) === -1;
185
+ option.hidden = isHidden;
186
+ if (this.isListHidden && !option.hidden) {
187
+ this.isListHidden = false;
188
+ }
189
+ // Groups should be visible if at least one item is visible within group
190
+ isGroupVisible = !isHidden || isGroupVisible;
191
+ }
192
+ }
193
+ updateGroupVisibility();
194
+ }
195
+ /**
196
+ * Method prevents cursor from jumping to the end of input.
197
+ *
198
+ * @param {React.FormEvent<IComboBox>} event Combobox event object
199
+ */
200
+ setCaretPosition(event) {
201
+ if ((0, utilities_1.isHTMLInputElement)(event.target)) {
202
+ const input = event.target;
203
+ const selectionEnd = input.selectionEnd;
204
+ if (selectionEnd !== input.value.length) {
205
+ window.requestAnimationFrame(() => {
206
+ input.selectionStart = selectionEnd;
207
+ input.selectionEnd = selectionEnd;
208
+ });
209
+ }
210
+ }
211
+ }
212
+ /**
213
+ * Method filters options and hides unmatched options.
214
+ *
215
+ * @param {React.FormEvent<IComboBox>} event Combobox event object
216
+ */
217
+ onInput(event) {
218
+ this.isListHidden = false;
219
+ if ((0, utilities_1.isHTMLInputElement)(event.target)) {
220
+ this.setCaretPosition(event);
221
+ const input = event.target;
222
+ this.query = input.value.trimStart().toLowerCase();
223
+ // Filter options
224
+ const baseCombobox = this.comboBox.current;
225
+ if (baseCombobox) {
226
+ this.updateHiddenOptions(baseCombobox.props.hoisted.currentOptions);
227
+ }
228
+ }
229
+ }
230
+ /**
231
+ * Method opens menu when user clicks on Combobox (input or button).
232
+ *
233
+ * @param event
234
+ */
235
+ onClick(event) {
236
+ this.setCaretPosition(event);
237
+ const baseCombobox = this.comboBox.current;
238
+ const isOpen = baseCombobox && baseCombobox.state.isOpen;
239
+ const isDisabled = this.props.disabled;
240
+ if (this.props.openMenuOnClick && baseCombobox && !isOpen && !isDisabled) {
241
+ baseCombobox.focus(true);
242
+ }
243
+ }
244
+ /**
245
+ * Method handles keydown event and does following.
246
+ * 1. Fix for bug(in fluentui sources) regarding keyboard navigation when last item is not visible.
247
+ * 2. Opens list when user enters any key.
248
+ *
249
+ * @param {React.FormEvent<HTMLInputElement>} event Keydown event
250
+ */
251
+ onKeyDown(event) {
252
+ let handled = false;
253
+ const baseCombobox = this.comboBox.current;
254
+ const isOpen = baseCombobox && baseCombobox.state.isOpen;
255
+ if (event.which === react_2.KeyCodes.down || event.which === react_2.KeyCodes.up) {
256
+ handled = this._setCyclingNavigation(event.which === react_2.KeyCodes.down);
257
+ }
258
+ if (handled) {
259
+ // Do not handle keydown of combobox
260
+ event.preventDefault();
261
+ event.stopPropagation();
262
+ }
263
+ else if (!this.ignoreOpenKeys.includes(event.key) && baseCombobox && !isOpen) {
264
+ // Open dropdown list on first key press instead of showing it right after focus
265
+ baseCombobox.focus(true);
266
+ }
267
+ }
268
+ /**
269
+ * Method resets search query.
270
+ */
271
+ reserQuery() {
272
+ this.query = '';
273
+ for (const option of this.props.options) {
274
+ delete option.hidden;
275
+ }
276
+ this.isListHidden = false;
277
+ this.setState({
278
+ isListHidden: this.isListHidden
279
+ });
280
+ }
281
+ /**
282
+ * Method which determines what is next visible item - it is used to fix bug in fluentui sources..
283
+ *
284
+ * @param {number} index Current index.
285
+ * @param {boolean} forward Dirrection to look up.
286
+ * @returns {ComboboxItemInfo | null} Combobox item object.
287
+ */
288
+ getNextVisibleItem(index, forward) {
289
+ const limit = this.props.options.length;
290
+ while (index >= 0 && index < limit) {
291
+ if (this.props.options[index] && !this.props.options[index].hidden) {
292
+ return {
293
+ option: this.props.options[index],
294
+ index
295
+ };
296
+ }
297
+ index = index + (forward ? 1 : -1);
298
+ }
299
+ return null;
300
+ }
301
+ /**
302
+ * Method is used as fix for bug(in fluentui sources) regarding keyboard navigation when last item is not visible.
303
+ *
304
+ * @param {boolean} forward Dirrection to look up.
305
+ * @returns {boolean} Returs true if method changed navigation.
306
+ */
307
+ _setCyclingNavigation(forward) {
308
+ const baseCombobox = this.comboBox.current;
309
+ if (baseCombobox && baseCombobox.state.currentPendingValueValidIndex >= 0) {
310
+ // Check if there exists any visible item in that direction
311
+ let index = baseCombobox.state.currentPendingValueValidIndex;
312
+ const limit = this.props.options.length - 1;
313
+ index = index + (forward ? 1 : -1);
314
+ let option = this.getNextVisibleItem(index, forward);
315
+ if (option) {
316
+ // Item exists - no need for custom logic as we are fixing issue in base control
317
+ return false;
318
+ }
319
+ // Item was not found - make circular navigation
320
+ option = this.getNextVisibleItem(forward ? 0 : limit, forward);
321
+ if (option) {
322
+ // We fixed issue in base combobox control -
323
+ // when last item is not visible and we navigate it
324
+ baseCombobox.setState({
325
+ currentPendingValueValidIndex: option.index,
326
+ currentPendingValue: option.option.text
327
+ });
328
+ return true;
329
+ }
330
+ }
331
+ return false;
332
+ }
333
+ /**
334
+ * Method for property 'useComboBoxAsMenuMinWidth' - method resolves current dropdown width and updates state with latest value.
335
+ * 'minWidth' from state is used to set callout size in render.
336
+ */
337
+ calculateMenuMinWidth() {
338
+ const comboBoxWrapper = this.comboBox.current?._comboBoxWrapper.current;
339
+ if (comboBoxWrapper &&
340
+ this.props.useComboBoxAsMenuMinWidth &&
341
+ comboBoxWrapper.clientWidth !== this.state.minWidth) {
342
+ this.setState({
343
+ minWidth: comboBoxWrapper.clientWidth
344
+ });
345
+ }
346
+ }
347
+ /**
348
+ * Method called only when property 'highlight' is true.
349
+ * Method called after each value live change - we need recheck if there is any visible item after search is done.
350
+ * 1. If there no any visible item - we hide menu callout.
351
+ * 2. If there is any visible item - we show menu callout.
352
+ *
353
+ * @param option Selected option.
354
+ * @param index Selected option's index.
355
+ * @param value Text value entered in input.
356
+ */
357
+ onPendingValueChanged(option, index, value) {
358
+ if (this.state.isListHidden !== this.isListHidden) {
359
+ this.setState({
360
+ isListHidden: this.isListHidden
361
+ });
362
+ }
363
+ if (this.props?.onPendingValueChanged) {
364
+ this.props?.onPendingValueChanged(option, index, value);
365
+ }
366
+ }
367
+ /**
368
+ * Public method to close menu callout if it is open.
369
+ */
370
+ dismissMenu() {
371
+ if (this.comboBox.current) {
372
+ this.comboBox.current.dismissMenu();
373
+ }
374
+ }
375
+ /**
376
+ * Public method to set the focus on the combo box.
377
+ */
378
+ setFocus() {
379
+ if (this.comboBox.current) {
380
+ this.comboBox.current.focus();
381
+ }
382
+ }
383
+ /**
384
+ * Method called only when property 'onRefresh' has been defined.
385
+ * It is called when click on the refresh buttonIcon.
386
+ */
387
+ handleRefreshButton() {
388
+ const baseCombobox = this.comboBox.current;
389
+ if (this.props.useComboBoxAsMenuMinWidth) {
390
+ this.calculateMenuMinWidth();
391
+ }
392
+ if (this.props.onRefresh) {
393
+ this.props.onRefresh();
394
+ baseCombobox?.focus(true);
395
+ }
396
+ }
397
+ /**
398
+ * Handle multiselect change by avoiding 'blur' event.
399
+ * Problem is that blur event uses suggested value and toggles selection for it.
400
+ *
401
+ * @param {React.FormEvent<IComboBox>} event on change
402
+ * @param {IComboBoxOption} option changed option
403
+ * @param {number} index option index
404
+ * @param {string} value changed value
405
+ */
406
+ onMultiSelectChange(event, option, index, value) {
407
+ // Ignore toggle if change triggered by blur
408
+ if (this.props.onChange && event.type !== 'blur') {
409
+ this.props.onChange(event, option, index, value);
410
+ }
411
+ }
412
+ /**
413
+ * Method is used to fix bug in fluent ui.
414
+ * Bug is for multiselect combobox - when keyboard navigation is used, then scrollbar position is not updated to make selected option visible in viewport.
415
+ */
416
+ onScrollToItem() {
417
+ // Multi select only
418
+ const selectedElement = this.selectedElement.current;
419
+ if (!this.props.multiSelect || !selectedElement) {
420
+ return;
421
+ }
422
+ const offsetParent = selectedElement.offsetParent;
423
+ if (offsetParent) {
424
+ const size = offsetParent.clientHeight;
425
+ const scrollSize = offsetParent.scrollHeight;
426
+ if (scrollSize > size) {
427
+ const elementTop = selectedElement.offsetTop;
428
+ const elementBottom = elementTop + selectedElement.clientHeight;
429
+ const scrollTop = offsetParent.scrollTop;
430
+ const scrollBottom = scrollTop + size;
431
+ if (!(elementTop >= scrollTop && elementBottom <= scrollBottom)) {
432
+ // Outline node is not visible in viewport
433
+ const diff = elementBottom > scrollBottom ? elementBottom - scrollBottom : elementTop - scrollTop;
434
+ offsetParent.scrollTop = scrollTop + diff;
435
+ }
436
+ }
437
+ }
438
+ }
439
+ /**
440
+ * Method returns class names string depending on props and component state.
441
+ *
442
+ * @param {InputValidationMessageInfo} messageInfo Error/warning message if applied
443
+ * @returns {string} Class names of root combobox element.
444
+ */
445
+ getClassNames(messageInfo) {
446
+ const { readOnly, disabled } = this.props;
447
+ const errorSuffix = messageInfo.message ? ValidationMessage_1.MESSAGE_TYPES_CLASSNAME_MAP.get(messageInfo.type) : undefined;
448
+ let classNames = `ts-ComboBox${messageInfo.message ? ' ts-ComboBox--' + errorSuffix : ''}`;
449
+ if (readOnly && !disabled) {
450
+ classNames += ' ts-ComboBox--readonly';
451
+ }
452
+ if (disabled) {
453
+ classNames += ' ts-ComboBox--disabled';
454
+ }
455
+ if ((0, UIDropdown_1.isDropdownEmpty)(this.props)) {
456
+ classNames += ' ts-ComboBox--empty';
457
+ }
458
+ return classNames;
459
+ }
460
+ /**
461
+ * Method returns properties for Autofill component(combobox's inner compnent for text input).
462
+ * Method handles 'highlight' and 'readOnly' properties.
463
+ *
464
+ * @returns {IAutofillProps} Properties for Autofill component.
465
+ */
466
+ getAutofillProps() {
467
+ const { highlight, readOnly, disabled } = this.props;
468
+ const autofill = {};
469
+ // Handle search highligh
470
+ if (highlight) {
471
+ autofill.onKeyDownCapture = this.onKeyDown;
472
+ }
473
+ const tabIndex = 'tabIndex' in this.props ? this.props.tabIndex : undefined;
474
+ // Handle readOnly property
475
+ if (readOnly && !disabled) {
476
+ autofill.readOnly = readOnly;
477
+ autofill.tabIndex = tabIndex;
478
+ // Adjust aria attributes for readonly
479
+ autofill['aria-disabled'] = undefined;
480
+ autofill['aria-readonly'] = true;
481
+ }
482
+ else if (disabled) {
483
+ autofill.disabled = undefined;
484
+ autofill.readOnly = true;
485
+ autofill.tabIndex = tabIndex;
486
+ }
487
+ return autofill;
488
+ }
489
+ /**
490
+ * @returns {JSX.Element}
491
+ */
492
+ render() {
493
+ const messageInfo = (0, ValidationMessage_1.getMessageInfo)(this.props);
494
+ let disabled = this.props.isForceEnabled ? false : !this.props.options.length;
495
+ if (this.props.readOnly) {
496
+ disabled = true;
497
+ }
498
+ return (react_1.default.createElement("div", { ref: this.props.wrapperRef, className: this.getClassNames(messageInfo) },
499
+ react_1.default.createElement(react_2.ComboBox, { componentRef: this.comboBox, ref: this.comboboxDomRef, disabled: disabled, iconButtonProps: {
500
+ iconProps: {
501
+ iconName: Icons_1.UiIcons.ArrowDown
502
+ }
503
+ }, calloutProps: {
504
+ calloutMaxHeight: 200,
505
+ popupProps: {
506
+ ref: this.menuDomRef
507
+ },
508
+ className: 'ts-Callout ts-Callout-Dropdown',
509
+ styles: {
510
+ ...(this.props.useComboBoxAsMenuMinWidth && {
511
+ calloutMain: {
512
+ minWidth: this.state.minWidth,
513
+ display: this.state.isListHidden ? 'none' : undefined
514
+ }
515
+ })
516
+ },
517
+ ...(0, UIDropdown_1.getCalloutCollisionTransformationProps)(this.calloutCollisionTransform, this.props.multiSelect, this.props.calloutCollisionTransformation)
518
+ }, styles: {
519
+ label: {
520
+ ...UILabel_1.labelGlobalStyle,
521
+ ...(this.props.disabled && {
522
+ opacity: '0.4'
523
+ }),
524
+ ...(this.props.required && {
525
+ selectors: {
526
+ '::after': {
527
+ content: `' *'`,
528
+ color: 'var(--vscode-inputValidation-errorBorder)',
529
+ paddingRight: 12
530
+ }
531
+ }
532
+ })
533
+ },
534
+ errorMessage: [messageInfo.style]
535
+ }, ...this.props, ...(this.props.highlight && {
536
+ onInput: this.onInput,
537
+ onMenuDismissed: this.reserQuery,
538
+ onResolveOptions: this.onResolveOptions,
539
+ onRenderItem: this.onRenderItem,
540
+ onRenderOption: this.onRenderOption,
541
+ placeholder: this.getPlaceholder(),
542
+ onPendingValueChanged: this.onPendingValueChanged
543
+ }), autofill: this.getAutofillProps(), ...(this.props.useComboBoxAsMenuMinWidth && {
544
+ // Use 'onMenuOpen', because there can be dynamic size of combobox
545
+ onMenuOpen: this.calculateMenuMinWidth.bind(this)
546
+ }), ...(this.props.openMenuOnClick && {
547
+ onClick: this.onClick.bind(this)
548
+ }), ...(this.props.onRefresh && {
549
+ onMenuOpen: this.handleRefreshButton,
550
+ onChange: this.handleChange
551
+ }), ...(this.props.isLoading && {
552
+ onRenderList: this.onRenderListLoading
553
+ }), ...(this.props.multiSelect && {
554
+ onScrollToItem: this.onScrollToItem,
555
+ ...(this.props.onChange && {
556
+ onChange: this.onMultiSelectChange
557
+ })
558
+ }), errorMessage: messageInfo.message })));
559
+ }
560
+ }
561
+ exports.UIComboBox = UIComboBox;
562
+ // Default values for public component properties
563
+ UIComboBox.defaultProps = { openMenuOnClick: true };
542
564
  //# sourceMappingURL=UIComboBox.js.map