@sap-ux/ui-components 1.14.1 → 1.15.0

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 (272) hide show
  1. package/dist/components/Icons.d.ts +151 -150
  2. package/dist/components/Icons.d.ts.map +1 -1
  3. package/dist/components/Icons.js +631 -628
  4. package/dist/components/Icons.js.map +1 -1
  5. package/dist/components/UIActionCallout/UIActionCallout.d.ts +64 -64
  6. package/dist/components/UIActionCallout/UIActionCallout.js +67 -67
  7. package/dist/components/UIActionCallout/index.d.ts +1 -1
  8. package/dist/components/UIActionCallout/index.js +17 -17
  9. package/dist/components/UIBreadcrumb/UIBreadcrumb.d.ts +23 -23
  10. package/dist/components/UIBreadcrumb/UIBreadcrumb.js +38 -38
  11. package/dist/components/UIBreadcrumb/index.d.ts +1 -1
  12. package/dist/components/UIBreadcrumb/index.js +17 -17
  13. package/dist/components/UIButton/UIActionButton.d.ts +23 -23
  14. package/dist/components/UIButton/UIActionButton.js +89 -89
  15. package/dist/components/UIButton/UIDefaultButton.d.ts +41 -41
  16. package/dist/components/UIButton/UIDefaultButton.js +255 -255
  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 -208
  40. package/dist/components/UIComboBox/UIComboBox.js +563 -563
  41. package/dist/components/UIComboBox/index.d.ts +1 -1
  42. package/dist/components/UIComboBox/index.js +17 -17
  43. package/dist/components/UIContextualMenu/UIContextualMenu.d.ts +31 -31
  44. package/dist/components/UIContextualMenu/UIContextualMenu.js +126 -126
  45. package/dist/components/UIContextualMenu/UIHighlightMenuOption.d.ts +19 -19
  46. package/dist/components/UIContextualMenu/UIHighlightMenuOption.js +50 -50
  47. package/dist/components/UIContextualMenu/index.d.ts +2 -2
  48. package/dist/components/UIContextualMenu/index.js +18 -18
  49. package/dist/components/UICreateSelect/UICreateSelect.d.ts +36 -36
  50. package/dist/components/UICreateSelect/UICreateSelect.js +172 -172
  51. package/dist/components/UICreateSelect/index.d.ts +1 -1
  52. package/dist/components/UICreateSelect/index.js +17 -17
  53. package/dist/components/UIDatePicker/UIDatePicker.d.ts +49 -49
  54. package/dist/components/UIDatePicker/UIDatePicker.js +72 -72
  55. package/dist/components/UIDatePicker/index.d.ts +1 -1
  56. package/dist/components/UIDatePicker/index.js +17 -17
  57. package/dist/components/UIDialog/UIDialog.d.ts +118 -118
  58. package/dist/components/UIDialog/UIDialog.js +281 -281
  59. package/dist/components/UIDialog/index.d.ts +1 -1
  60. package/dist/components/UIDialog/index.js +17 -17
  61. package/dist/components/UIDropdown/UIDropdown.d.ts +94 -94
  62. package/dist/components/UIDropdown/UIDropdown.js +224 -224
  63. package/dist/components/UIDropdown/index.d.ts +2 -2
  64. package/dist/components/UIDropdown/index.js +18 -18
  65. package/dist/components/UIDropdown/utils.d.ts +20 -20
  66. package/dist/components/UIDropdown/utils.js +43 -43
  67. package/dist/components/UIFlexibleTable/RowActions.d.ts +16 -16
  68. package/dist/components/UIFlexibleTable/RowActions.js +73 -73
  69. package/dist/components/UIFlexibleTable/RowData.d.ts +16 -16
  70. package/dist/components/UIFlexibleTable/RowData.js +111 -111
  71. package/dist/components/UIFlexibleTable/UIFlexibleTable.d.ts +11 -11
  72. package/dist/components/UIFlexibleTable/UIFlexibleTable.js +280 -280
  73. package/dist/components/UIFlexibleTable/UIFlexibleTableActionButton.d.ts +20 -20
  74. package/dist/components/UIFlexibleTable/UIFlexibleTableActionButton.js +20 -20
  75. package/dist/components/UIFlexibleTable/UIFlexibleTableRow.d.ts +26 -26
  76. package/dist/components/UIFlexibleTable/UIFlexibleTableRow.js +219 -219
  77. package/dist/components/UIFlexibleTable/UIFlexibleTableRowActionButton.d.ts +20 -20
  78. package/dist/components/UIFlexibleTable/UIFlexibleTableRowActionButton.js +19 -19
  79. package/dist/components/UIFlexibleTable/UIFlexibleTableRowNoData.d.ts +15 -15
  80. package/dist/components/UIFlexibleTable/UIFlexibleTableRowNoData.js +28 -28
  81. package/dist/components/UIFlexibleTable/index.d.ts +5 -5
  82. package/dist/components/UIFlexibleTable/index.js +21 -21
  83. package/dist/components/UIFlexibleTable/types.d.ts +143 -143
  84. package/dist/components/UIFlexibleTable/types.js +14 -14
  85. package/dist/components/UIFlexibleTable/utils.d.ts +25 -25
  86. package/dist/components/UIFlexibleTable/utils.js +49 -49
  87. package/dist/components/UIFocusZone/UIFocusTrapZone.d.ts +22 -22
  88. package/dist/components/UIFocusZone/UIFocusTrapZone.js +33 -33
  89. package/dist/components/UIFocusZone/UIFocusZone.d.ts +23 -23
  90. package/dist/components/UIFocusZone/UIFocusZone.js +35 -35
  91. package/dist/components/UIFocusZone/index.d.ts +2 -2
  92. package/dist/components/UIFocusZone/index.js +18 -18
  93. package/dist/components/UIIcon/UIIcon.d.ts +24 -24
  94. package/dist/components/UIIcon/UIIcon.js +37 -37
  95. package/dist/components/UIIcon/index.d.ts +1 -1
  96. package/dist/components/UIIcon/index.js +17 -17
  97. package/dist/components/UIInput/UITextInput.d.ts +51 -51
  98. package/dist/components/UIInput/UITextInput.js +244 -244
  99. package/dist/components/UIInput/index.d.ts +1 -1
  100. package/dist/components/UIInput/index.js +17 -17
  101. package/dist/components/UILabel/UILabel.d.ts +30 -30
  102. package/dist/components/UILabel/UILabel.js +64 -64
  103. package/dist/components/UILabel/index.d.ts +1 -1
  104. package/dist/components/UILabel/index.js +17 -17
  105. package/dist/components/UILink/UILink.d.ts +25 -25
  106. package/dist/components/UILink/UILink.js +71 -71
  107. package/dist/components/UILink/index.d.ts +1 -1
  108. package/dist/components/UILink/index.js +17 -17
  109. package/dist/components/UIList/UIList.d.ts +31 -31
  110. package/dist/components/UIList/UIList.js +120 -120
  111. package/dist/components/UIList/index.d.ts +1 -1
  112. package/dist/components/UIList/index.js +17 -17
  113. package/dist/components/UILoader/UILoader.d.ts +27 -27
  114. package/dist/components/UILoader/UILoader.js +78 -78
  115. package/dist/components/UILoader/index.d.ts +1 -1
  116. package/dist/components/UILoader/index.js +17 -17
  117. package/dist/components/UIMessageBar/UIMessageBar.d.ts +25 -25
  118. package/dist/components/UIMessageBar/UIMessageBar.js +56 -56
  119. package/dist/components/UIMessageBar/index.d.ts +1 -1
  120. package/dist/components/UIMessageBar/index.js +17 -17
  121. package/dist/components/UIModal/UIModal.d.ts +23 -23
  122. package/dist/components/UIModal/UIModal.js +43 -43
  123. package/dist/components/UIModal/index.d.ts +1 -1
  124. package/dist/components/UIModal/index.js +17 -17
  125. package/dist/components/UIOverlay/UIOverlay.d.ts +22 -22
  126. package/dist/components/UIOverlay/UIOverlay.js +38 -38
  127. package/dist/components/UIOverlay/index.d.ts +1 -1
  128. package/dist/components/UIOverlay/index.js +17 -17
  129. package/dist/components/UIPersona/UIPersona.d.ts +27 -27
  130. package/dist/components/UIPersona/UIPersona.js +48 -48
  131. package/dist/components/UIPersona/index.d.ts +1 -1
  132. package/dist/components/UIPersona/index.js +17 -17
  133. package/dist/components/UIQuickNavigation/UIQuickNavigation.d.ts +31 -0
  134. package/dist/components/UIQuickNavigation/UIQuickNavigation.d.ts.map +1 -0
  135. package/dist/components/UIQuickNavigation/UIQuickNavigation.js +251 -0
  136. package/dist/components/UIQuickNavigation/UIQuickNavigation.js.map +1 -0
  137. package/dist/components/UIQuickNavigation/UIQuickNavigation.scss +33 -0
  138. package/dist/components/UIQuickNavigation/index.d.ts +2 -0
  139. package/dist/components/UIQuickNavigation/index.d.ts.map +1 -0
  140. package/dist/components/UIQuickNavigation/index.js +18 -0
  141. package/dist/components/UIQuickNavigation/index.js.map +1 -0
  142. package/dist/components/UISearchBox/UISearchBox.d.ts +22 -22
  143. package/dist/components/UISearchBox/UISearchBox.js +155 -155
  144. package/dist/components/UISearchBox/index.d.ts +3 -3
  145. package/dist/components/UISearchBox/index.js +17 -17
  146. package/dist/components/UISection/UISection.d.ts +34 -34
  147. package/dist/components/UISection/UISection.js +44 -44
  148. package/dist/components/UISection/UISections.d.ts +249 -249
  149. package/dist/components/UISection/UISections.js +707 -707
  150. package/dist/components/UISection/UISplitter.d.ts +96 -96
  151. package/dist/components/UISection/UISplitter.js +220 -220
  152. package/dist/components/UISection/index.d.ts +3 -3
  153. package/dist/components/UISection/index.js +19 -19
  154. package/dist/components/UISeparator/UISeparator.d.ts +25 -25
  155. package/dist/components/UISeparator/UISeparator.js +65 -65
  156. package/dist/components/UISeparator/index.d.ts +1 -1
  157. package/dist/components/UISeparator/index.js +17 -17
  158. package/dist/components/UITable/UITable-helper.d.ts +88 -88
  159. package/dist/components/UITable/UITable-helper.js +263 -263
  160. package/dist/components/UITable/UITable.d.ts +213 -213
  161. package/dist/components/UITable/UITable.js +779 -779
  162. package/dist/components/UITable/index.d.ts +2 -2
  163. package/dist/components/UITable/index.js +18 -18
  164. package/dist/components/UITable/types.d.ts +77 -77
  165. package/dist/components/UITable/types.js +28 -28
  166. package/dist/components/UITabs/UITabs.d.ts +28 -28
  167. package/dist/components/UITabs/UITabs.js +70 -70
  168. package/dist/components/UITabs/index.d.ts +1 -1
  169. package/dist/components/UITabs/index.js +17 -17
  170. package/dist/components/UIToggle/UIToggle.d.ts +39 -39
  171. package/dist/components/UIToggle/UIToggle.js +181 -181
  172. package/dist/components/UIToggle/index.d.ts +1 -1
  173. package/dist/components/UIToggle/index.js +17 -17
  174. package/dist/components/UIToggleGroup/UIToggleGroup.d.ts +31 -31
  175. package/dist/components/UIToggleGroup/UIToggleGroup.js +139 -139
  176. package/dist/components/UIToggleGroup/UIToggleGroup.types.d.ts +22 -22
  177. package/dist/components/UIToggleGroup/UIToggleGroup.types.js +2 -2
  178. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.d.ts +25 -25
  179. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.js +77 -77
  180. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.types.d.ts +10 -10
  181. package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.types.js +2 -2
  182. package/dist/components/UIToggleGroup/UIToggleGroupOption/index.d.ts +2 -2
  183. package/dist/components/UIToggleGroup/UIToggleGroupOption/index.js +18 -18
  184. package/dist/components/UIToggleGroup/index.d.ts +2 -2
  185. package/dist/components/UIToggleGroup/index.js +18 -18
  186. package/dist/components/UIToolbar/UIToolbar.d.ts +36 -36
  187. package/dist/components/UIToolbar/UIToolbar.js +104 -104
  188. package/dist/components/UIToolbar/UIToolbarColumn.d.ts +7 -7
  189. package/dist/components/UIToolbar/UIToolbarColumn.js +33 -33
  190. package/dist/components/UIToolbar/UIToolbarDivider.d.ts +27 -27
  191. package/dist/components/UIToolbar/UIToolbarDivider.js +52 -52
  192. package/dist/components/UIToolbar/index.d.ts +3 -3
  193. package/dist/components/UIToolbar/index.js +19 -19
  194. package/dist/components/UITooltip/UITooltip.d.ts +29 -29
  195. package/dist/components/UITooltip/UITooltip.js +77 -77
  196. package/dist/components/UITooltip/UITooltipUtils.d.ts +17 -17
  197. package/dist/components/UITooltip/UITooltipUtils.js +45 -45
  198. package/dist/components/UITooltip/index.d.ts +2 -2
  199. package/dist/components/UITooltip/index.js +18 -18
  200. package/dist/components/UITranslationInput/UIFormattedText.d.ts +46 -46
  201. package/dist/components/UITranslationInput/UIFormattedText.js +121 -121
  202. package/dist/components/UITranslationInput/UILoadButton.d.ts +52 -52
  203. package/dist/components/UITranslationInput/UILoadButton.js +109 -109
  204. package/dist/components/UITranslationInput/UITranslationButton.d.ts +14 -14
  205. package/dist/components/UITranslationInput/UITranslationButton.js +88 -88
  206. package/dist/components/UITranslationInput/UITranslationButton.types.d.ts +67 -67
  207. package/dist/components/UITranslationInput/UITranslationButton.types.js +21 -21
  208. package/dist/components/UITranslationInput/UITranslationInput.d.ts +25 -25
  209. package/dist/components/UITranslationInput/UITranslationInput.js +169 -169
  210. package/dist/components/UITranslationInput/UITranslationUtils.d.ts +64 -64
  211. package/dist/components/UITranslationInput/UITranslationUtils.js +168 -168
  212. package/dist/components/UITranslationInput/defaults.d.ts +2 -2
  213. package/dist/components/UITranslationInput/defaults.js +15 -15
  214. package/dist/components/UITranslationInput/index.d.ts +2 -2
  215. package/dist/components/UITranslationInput/index.js +18 -18
  216. package/dist/components/UITreeDropdown/UITreeDropdown.d.ts +265 -265
  217. package/dist/components/UITreeDropdown/UITreeDropdown.js +660 -660
  218. package/dist/components/UITreeDropdown/index.d.ts +1 -1
  219. package/dist/components/UITreeDropdown/index.js +17 -17
  220. package/dist/components/UIVerticalDivider/UIVerticalDivider.d.ts +23 -23
  221. package/dist/components/UIVerticalDivider/UIVerticalDivider.js +41 -41
  222. package/dist/components/UIVerticalDivider/index.d.ts +1 -1
  223. package/dist/components/UIVerticalDivider/index.js +17 -17
  224. package/dist/components/UIVirtualList/UIAutoSizer.d.ts +22 -22
  225. package/dist/components/UIVirtualList/UIAutoSizer.js +33 -33
  226. package/dist/components/UIVirtualList/UICellMeasurer.d.ts +23 -23
  227. package/dist/components/UIVirtualList/UICellMeasurer.js +33 -33
  228. package/dist/components/UIVirtualList/UIVirtualList.d.ts +43 -43
  229. package/dist/components/UIVirtualList/UIVirtualList.js +70 -70
  230. package/dist/components/UIVirtualList/index.d.ts +3 -3
  231. package/dist/components/UIVirtualList/index.js +19 -19
  232. package/dist/components/index.d.ts +39 -38
  233. package/dist/components/index.d.ts.map +1 -1
  234. package/dist/components/index.js +55 -54
  235. package/dist/components/index.js.map +1 -1
  236. package/dist/helper/ValidationMessage/MessageWrapper.d.ts +17 -17
  237. package/dist/helper/ValidationMessage/MessageWrapper.js +34 -34
  238. package/dist/helper/ValidationMessage/index.d.ts +2 -2
  239. package/dist/helper/ValidationMessage/index.js +18 -18
  240. package/dist/helper/ValidationMessage/utils.d.ts +31 -31
  241. package/dist/helper/ValidationMessage/utils.js +121 -121
  242. package/dist/index.d.ts +2 -2
  243. package/dist/index.js +18 -18
  244. package/dist/utilities/DeepMerge.d.ts +10 -10
  245. package/dist/utilities/DeepMerge.js +48 -48
  246. package/dist/utilities/Dom.d.ts +14 -14
  247. package/dist/utilities/Dom.d.ts.map +1 -1
  248. package/dist/utilities/Dom.js +23 -23
  249. package/dist/utilities/Dom.js.map +1 -1
  250. package/dist/utilities/Focus.d.ts +14 -14
  251. package/dist/utilities/Focus.js +34 -34
  252. package/dist/utilities/Id.d.ts +2 -2
  253. package/dist/utilities/Id.js +5 -5
  254. package/dist/utilities/Keys.d.ts +2 -2
  255. package/dist/utilities/Keys.js +5 -5
  256. package/dist/utilities/index.d.ts +4 -4
  257. package/dist/utilities/index.js +20 -20
  258. package/package.json +2 -2
  259. package/storybook/666.9eb67cb9.iframe.bundle.js +7 -0
  260. package/storybook/909.5e5ef92e.iframe.bundle.js +1 -0
  261. package/storybook/{930.3177b0dc.iframe.bundle.js → 930.1b3c5615.iframe.bundle.js} +2 -2
  262. package/storybook/UIQuickNavigation-story.14c63c2c.iframe.bundle.js +1 -0
  263. package/storybook/iframe.html +3 -3
  264. package/storybook/index.json +1 -1
  265. package/storybook/main.3da10e91.iframe.bundle.js +1 -0
  266. package/storybook/project.json +1 -1
  267. package/storybook/runtime~main.6f623654.iframe.bundle.js +2 -0
  268. package/storybook/stories.json +1 -1
  269. package/storybook/666.7332043d.iframe.bundle.js +0 -7
  270. package/storybook/909.dde4cce0.iframe.bundle.js +0 -1
  271. package/storybook/main.5f68bcca.iframe.bundle.js +0 -1
  272. package/storybook/runtime~main.a213c0ae.iframe.bundle.js +0 -2
@@ -1,780 +1,780 @@
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.UITable = void 0;
7
- const react_1 = __importDefault(require("react"));
8
- const react_2 = require("@fluentui/react");
9
- const UICheckbox_1 = require("../UICheckbox");
10
- const UIInput_1 = require("../UIInput");
11
- const UIDropdown_1 = require("../UIDropdown");
12
- const UIComboBox_1 = require("../UIComboBox");
13
- const UIDatePicker_1 = require("../UIDatePicker");
14
- const UITable_helper_1 = require("./UITable-helper");
15
- const types_1 = require("./types");
16
- require("./UITable.scss");
17
- /**
18
- * UITable component
19
- * based on: https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist
20
- *
21
- * @exports
22
- * @class {UITable}
23
- * @extends {React.Component<UITableProps, UITableState>}
24
- */
25
- class UITable extends react_1.default.Component {
26
- /**
27
- * Initializes component properties.
28
- *
29
- * @param props
30
- */
31
- constructor(props) {
32
- super(props);
33
- this.inputRefs = {};
34
- this.activeElement = {};
35
- this.caretPosition = -1;
36
- this._onRenderRow = (props) => {
37
- if (!props) {
38
- return null;
39
- }
40
- const toggle = !!this.props.renderInputs;
41
- return react_1.default.createElement(react_2.DetailsRow, { "data-selection-toggle": toggle, rowFieldsAs: this.renderRowFields.bind(this), ...props });
42
- };
43
- this.onComboBoxChange = (option) => {
44
- this.setState((prevState) => {
45
- const editedCell = prevState.editedCell ?? this.activeElement;
46
- if (editedCell && option) {
47
- editedCell.newValue = option.text;
48
- }
49
- return { editedCell };
50
- });
51
- };
52
- this.onDropdownCellValueChange = (selectedOption, item, rowIndex, column) => {
53
- const newValue = selectedOption.key;
54
- if (typeof this.props.onSave === 'function' &&
55
- typeof rowIndex === 'number' &&
56
- Number.isInteger(rowIndex) &&
57
- column) {
58
- const currentValue = this.props.items[rowIndex][column.key];
59
- const editedCell = { rowIndex, item, column, errorMessage: undefined };
60
- if (currentValue !== newValue) {
61
- this.props.onSave(editedCell, newValue);
62
- }
63
- const field = column?.fieldName;
64
- if (field && item) {
65
- item[field] = newValue;
66
- }
67
- }
68
- this.cancelEdit();
69
- };
70
- this.state = {
71
- columns: props.columns || [],
72
- items: props.items || []
73
- };
74
- this.tableRef = react_1.default.createRef();
75
- this.selection = new react_2.Selection({
76
- onSelectionChanged: () => {
77
- if (typeof this.props.onSelectionChange !== 'function') {
78
- return;
79
- }
80
- this.props.onSelectionChange(this.selection.getSelectedIndices());
81
- }
82
- });
83
- if (this.props.selectionRef) {
84
- this.props.selectionRef.current = this.selection;
85
- }
86
- this.onTextInputChange = this.onTextInputChange.bind(this);
87
- this.onComboBoxChange = this.onComboBoxChange.bind(this);
88
- this.onDocumentMousedown = this.onDocumentMousedown.bind(this);
89
- this.onKeyDown = this.onKeyDown.bind(this);
90
- this.onComboBoxKeyDownCapture = this.onComboBoxKeyDownCapture.bind(this);
91
- this.validateCell = this.validateCell.bind(this);
92
- this.editNextCell = this.editNextCell.bind(this);
93
- this._onColumnClick = this._onColumnClick.bind(this);
94
- this._onCellRender = this._onCellRender.bind(this);
95
- this._onRenderCheckbox = this._onRenderCheckbox.bind(this);
96
- this._onRenderField = this._onRenderField?.bind(this);
97
- this._onRenderRow = this._onRenderRow?.bind(this);
98
- this._onRenderItemColumn = this._onRenderItemColumn?.bind(this);
99
- this._onCellActivation = this._onCellActivation?.bind(this);
100
- }
101
- componentDidMount() {
102
- this.onDocMousedown = this.onDocumentMousedown;
103
- document.addEventListener('mousedown', this.onDocMousedown, true);
104
- window.dispatchEvent(new Event('resize'));
105
- this._setTextRefs();
106
- }
107
- componentWillUnmount() {
108
- document.removeEventListener('mousedown', this.onDocMousedown);
109
- }
110
- /**
111
- * On component update.
112
- *
113
- * @param prevProps
114
- * @param prevState
115
- */
116
- componentDidUpdate(prevProps, prevState) {
117
- const scrollContainer = document.querySelector('.ms-ScrollablePane--contentContainer');
118
- if (scrollContainer) {
119
- const left = scrollContainer.scrollLeft || 0;
120
- requestAnimationFrame(() => (scrollContainer.scrollLeft = left));
121
- }
122
- if (prevProps.items !== this.props.items) {
123
- this.setState({ items: this.props.items });
124
- this._setTextRefs();
125
- }
126
- if (prevProps.columns !== this.props.columns) {
127
- this.setState({ columns: this.props.columns });
128
- }
129
- if (prevProps.dataSetKey !== this.props.dataSetKey) {
130
- this.setState({ editedCell: undefined });
131
- }
132
- if (typeof this.props.selectedRow !== 'undefined' && prevProps.selectedRow !== this.props.selectedRow) {
133
- (0, UITable_helper_1.scrollToRow)(this.props.selectedRow, this.tableRef?.current);
134
- }
135
- if (this.props.scrollToAddedRow) {
136
- const dataSetChanged = this.props.dataSetKey !== prevProps.dataSetKey;
137
- const { items } = this.state;
138
- const { items: prevItems } = prevState;
139
- const itemsDelta = items.length - prevItems.length;
140
- const shouldScrollToNewRow = !dataSetChanged && itemsDelta === 1;
141
- if (shouldScrollToNewRow && this.tableRef && this.tableRef.current) {
142
- const newRowIndex = items.length - 1;
143
- this.tableRef.current.scrollToIndex(newRowIndex);
144
- }
145
- }
146
- const { selectedColumnId } = this.props;
147
- const { selectedColumnId: prevSelectedColumnId } = prevProps;
148
- // Due to table rendering using columns data from state, instead of props,
149
- // to sync selected column change callback with rendered dataset change
150
- // selected column id/key needs to be stored on a state level along with columns data
151
- if (selectedColumnId !== prevSelectedColumnId) {
152
- this.setState({ selectedColumnId });
153
- }
154
- const columnIsSelected = typeof this.state.selectedColumnId !== 'undefined';
155
- const selectedColumnDidChange = prevState.selectedColumnId !== this.state.selectedColumnId;
156
- if (columnIsSelected && selectedColumnDidChange) {
157
- (0, UITable_helper_1.scrollToColumn)(this.state.selectedColumnId || '', this.state.columns, this.props.selectedRow || 0, this.props.showRowNumbers);
158
- }
159
- this._restoreCaretPosition();
160
- }
161
- /**
162
- * Restores the caret position. Caret position gets lost when validation finds issue in cell.
163
- */
164
- _restoreCaretPosition() {
165
- const editedCell = this.state.editedCell;
166
- if (this.caretPosition !== -1 && typeof editedCell?.rowIndex === 'number' && editedCell.column?.key) {
167
- const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
168
- const input = cell.querySelector('input');
169
- if (input && input.selectionStart !== this.caretPosition) {
170
- input.setSelectionRange(this.caretPosition, this.caretPosition);
171
- this.caretPosition = -1;
172
- }
173
- }
174
- }
175
- _setTextRefs() {
176
- if (this.props.columns && this.props.items) {
177
- for (const rowIndexTmp in this.props.items) {
178
- for (const col of this.props.columns) {
179
- if (col.editable === true && this.inputRefs) {
180
- this.inputRefs[rowIndexTmp] = this.inputRefs[rowIndexTmp] || {};
181
- this.inputRefs[rowIndexTmp][col.key] = react_1.default.createRef();
182
- }
183
- }
184
- }
185
- }
186
- }
187
- /**
188
- * On render row fields event.
189
- *
190
- * @param props
191
- * @returns {JSX.Element}
192
- */
193
- renderRowFields(props) {
194
- // disabled is set to false when selectionMode === undefined || selectionMode === SelectionMode.single
195
- let disabled = false;
196
- const selectionMode = this.props.selectionMode;
197
- if (selectionMode === react_2.SelectionMode.multiple || selectionMode === react_2.SelectionMode.none) {
198
- disabled = true;
199
- }
200
- return (react_1.default.createElement("div", { "data-selection-disabled": disabled },
201
- react_1.default.createElement(react_2.DetailsRowFields, { ...props })));
202
- }
203
- /**
204
- * On render field event.
205
- *
206
- * @param props
207
- * @param defaultRender
208
- * @returns {null | JSX.Element}
209
- */
210
- _onRenderField(props, defaultRender) {
211
- if (!props || !defaultRender) {
212
- return null;
213
- }
214
- const cell = defaultRender(props);
215
- const onClick = (e) => {
216
- const target = e?.target;
217
- const targetTag = target?.tagName;
218
- if (['INPUT', 'TEXTAREA', 'SELECT'].includes(targetTag)) {
219
- return;
220
- }
221
- const { item, rowIndex, column } = this.activeElement;
222
- this._onCellClick(e, item, rowIndex || 0, column);
223
- };
224
- // in app-migrator, show a warning message for library projects on main migration view
225
- if (props.item.hideCells && props.column.fieldName === 'moduleName' && !props.item.status) {
226
- return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" },
227
- cell?.props?.children || null,
228
- react_1.default.createElement("div", { className: "table-item-warning" }, "This is a reuse library and does not require input during migration")));
229
- }
230
- else {
231
- return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" }, cell?.props?.children || null));
232
- }
233
- }
234
- // just sets the active element property on the table, to track it later
235
- /**
236
- * On cell activation event.
237
- *
238
- * @param item
239
- * @param rowIndex
240
- * @param ev
241
- */
242
- _onCellActivation(item, rowIndex, ev) {
243
- const rowEl = ev?.target?.closest('.ms-DetailsRow');
244
- let column = {};
245
- const cells = rowEl?.querySelectorAll('.ms-DetailsRow-fields .ms-DetailsRow-cell');
246
- if (!cells || !cells.length) {
247
- return;
248
- }
249
- // focusing cell, not the row
250
- const cellEl = ev?.target?.closest('.ms-DetailsRow-cell');
251
- if (cellEl) {
252
- const cellIdx = Array.from(cells).indexOf(cellEl);
253
- if (cellIdx === -1) {
254
- return;
255
- }
256
- column = this.props.columns[cellIdx];
257
- if (!column) {
258
- return;
259
- }
260
- }
261
- this.activeElement = { item, rowIndex: rowIndex || 0, column };
262
- if (this.props.renderInputs && column?.editable) {
263
- const isDropdown = this.activeElement?.column?.columnControlType === types_1.ColumnControlType?.UIDropdown;
264
- if (!isDropdown && this.state.editedCell?.column?.key !== this.activeElement?.column?.key) {
265
- this.setState({ editedCell: this.activeElement });
266
- }
267
- }
268
- }
269
- /**
270
- * On render item column event.
271
- *
272
- * @param {UIDocument} item
273
- * @param {number} index
274
- * @param {UIColumn} column
275
- * @returns {React.ReactNode}
276
- */
277
- _onRenderItemColumn(item, index, column) {
278
- if (column?.key === '__row_number__') {
279
- return react_1.default.createElement("div", { className: "ms-DetailsList-row-number" }, (index || 0) + 1);
280
- }
281
- return item[column?.fieldName || ''] || '';
282
- }
283
- // Replace weird radio-button-checkboxes with proper checkboxes
284
- /**
285
- * On render checkbox event.
286
- *
287
- * @param {IDetailsListCheckboxProps | undefined} props
288
- * @returns {React.ReactElement}
289
- */
290
- _onRenderCheckbox(props) {
291
- return react_1.default.createElement(UICheckbox_1.UICheckbox, { ...props });
292
- }
293
- // COLUMN HEADER SORT
294
- /**
295
- * On column click event.
296
- *
297
- * @param ev
298
- * @param column
299
- */
300
- _onColumnClick(ev, column) {
301
- const { columns, items } = this.state;
302
- const newColumns = columns.slice();
303
- const currColumn = newColumns.filter((currCol) => column.key === currCol.key)[0];
304
- newColumns.forEach((newCol) => {
305
- if (newCol === currColumn) {
306
- currColumn.isSortedDescending = !currColumn.isSortedDescending;
307
- currColumn.isSorted = true;
308
- }
309
- else {
310
- newCol.isSorted = false;
311
- newCol.isSortedDescending = false;
312
- }
313
- });
314
- const field = currColumn.fieldName || currColumn.name || '';
315
- const newItems = (0, UITable_helper_1._copyAndSort)(items, field, currColumn.isSortedDescending);
316
- this.setState({ columns: newColumns, items: newItems });
317
- }
318
- // CELL EDITING
319
- /**
320
- * On start edit event call.
321
- *
322
- * @param rowIndex
323
- * @param item
324
- * @param column
325
- * @param errorMessage
326
- */
327
- startEdit(rowIndex, item, column, errorMessage) {
328
- const { editedCell } = this.state;
329
- const isAlreadyInEdit = editedCell?.rowIndex === rowIndex && column?.key && editedCell?.column?.key === column?.key;
330
- if (!isAlreadyInEdit) {
331
- this.setState({ editedCell: { rowIndex, item, column, errorMessage } });
332
- if (!this.props.renderInputs) {
333
- this.rerenderTable();
334
- }
335
- }
336
- requestAnimationFrame(() => {
337
- if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
338
- this.inputRefs?.[rowIndex][column?.key]?.current?.select();
339
- }
340
- else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
341
- column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
342
- const combo = this.inputRefs?.[rowIndex][column?.key];
343
- (0, UITable_helper_1.getComboBoxInput)(combo)?.focus();
344
- }
345
- else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
346
- this.inputRefs?.[rowIndex][column?.key]?.current?.select();
347
- }
348
- else if (column?.key) {
349
- const otherElement = this.inputRefs?.[rowIndex][column.key]?.current;
350
- otherElement.focus();
351
- }
352
- });
353
- }
354
- rerenderTable() {
355
- if (this.tableRef.current) {
356
- this.tableRef.current.forceUpdate();
357
- }
358
- }
359
- cancelEdit() {
360
- this.caretPosition = -1;
361
- this.setState({ editedCell: undefined });
362
- this.rerenderTable();
363
- }
364
- /**
365
- * On save cell event.
366
- *
367
- * @param cancelEdit
368
- * @param value
369
- */
370
- saveCell(cancelEdit = false, value) {
371
- this.caretPosition = -1;
372
- if (typeof this.props.onSave === 'function' && this.state.editedCell) {
373
- const { rowIndex, column } = this.state.editedCell;
374
- if (column?.columnControlType !== types_1.ColumnControlType.UIDropdown && !this.state.editedCell.errorMessage) {
375
- let compRef;
376
- if (column && this?.inputRefs?.[rowIndex]?.[column.key]) {
377
- compRef = this?.inputRefs[rowIndex][column.key];
378
- }
379
- const currentValue = column && this.props.items[rowIndex][column.key];
380
- let refValue = '';
381
- if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
382
- refValue = compRef?.current?.value || '';
383
- }
384
- else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
385
- refValue = compRef?.current?.value || '';
386
- }
387
- else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
388
- column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
389
- const combo = compRef;
390
- refValue = (0, UITable_helper_1.getComboBoxInput)(combo)?.value || '';
391
- }
392
- const newValue = value ?? refValue;
393
- if (currentValue !== newValue) {
394
- this.props.onSave(this.state.editedCell, newValue);
395
- }
396
- const item = this.state.editedCell?.item;
397
- const field = column?.fieldName;
398
- if (field && item) {
399
- item[field] = newValue;
400
- }
401
- }
402
- }
403
- if (cancelEdit) {
404
- this.cancelEdit();
405
- }
406
- }
407
- /**
408
- * On mouse down event.
409
- *
410
- * @param e
411
- */
412
- onDocumentMousedown(e) {
413
- const target = e.target; // needed for TSC
414
- if (target.closest('.ms-TextField, .ms-ComboBox, .ms-ComboBox-option, .ui-DatePicker') &&
415
- !this.props.renderInputs) {
416
- return;
417
- }
418
- if (this.state.editedCell) {
419
- if (this.state.editedCell.errorMessage) {
420
- e.preventDefault();
421
- }
422
- else {
423
- this.saveCell(true);
424
- }
425
- }
426
- }
427
- /**
428
- * On key down event.
429
- *
430
- * @param {React.KeyboardEvent<Element | IDropdown>} e
431
- * @returns {void}
432
- */
433
- onKeyDown(e) {
434
- if (!['Enter', 'Tab', 'Escape', 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
435
- return;
436
- }
437
- const isArrow = ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key);
438
- const isInput = e.target.tagName === 'INPUT';
439
- if (isArrow && isInput) {
440
- e.stopPropagation();
441
- return;
442
- }
443
- e.preventDefault();
444
- if (e.key === 'Escape') {
445
- this.cancelEdit();
446
- (0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props).catch(() => {
447
- // Ignore focus cell error
448
- });
449
- (0, UITable_helper_1.showFocus)();
450
- return;
451
- }
452
- if (this.state.editedCell?.errorMessage) {
453
- return;
454
- }
455
- e.stopPropagation();
456
- if (e.key === 'Enter' || e.key === 'Tab') {
457
- this.editNextCell(e.key, e.shiftKey);
458
- }
459
- }
460
- /**
461
- * On ComboBox keydown event call.
462
- *
463
- * @param e
464
- */
465
- onComboBoxKeyDownCapture(e) {
466
- if (e.key === 'Enter' || e.key === 'Tab') {
467
- // stop Enter from opening combobox
468
- e.stopPropagation();
469
- e.preventDefault();
470
- this.editNextCell(e.key, e.shiftKey);
471
- }
472
- }
473
- /**
474
- * On Edit next cell.
475
- *
476
- * @param key
477
- * @param shiftKey
478
- */
479
- editNextCell(key, shiftKey) {
480
- this.saveCell();
481
- let direction = '';
482
- if (key === 'Enter') {
483
- direction = shiftKey ? 'up' : 'down';
484
- }
485
- else if (key === 'Tab') {
486
- direction = shiftKey ? 'left' : 'right';
487
- }
488
- if (direction) {
489
- (0, UITable_helper_1.hideFocus)();
490
- }
491
- setTimeout(() => {
492
- (0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props, direction)
493
- .then(() => {
494
- if (!direction) {
495
- (0, UITable_helper_1.showFocus)();
496
- return;
497
- }
498
- (0, UITable_helper_1.hideFocus)();
499
- const { rowIndex, item, column } = this.activeElement;
500
- this.startEdit(rowIndex, item, column);
501
- })
502
- .catch((e) => {
503
- throw e;
504
- });
505
- }, 100);
506
- }
507
- /**
508
- * On Cell click.
509
- *
510
- * @param e
511
- * @param item
512
- * @param rowIndex
513
- * @param column
514
- */
515
- _onCellClick(e, item, rowIndex, column) {
516
- const previousCellHasErrors = this.state.editedCell?.errorMessage;
517
- if (previousCellHasErrors) {
518
- return;
519
- }
520
- if (this.props.renderInputs) {
521
- return;
522
- }
523
- const el = e?.target;
524
- requestAnimationFrame(() => {
525
- // check the checkbox & focus the clicked cell
526
- if (el) {
527
- const fz = el.closest('.ms-FocusZone');
528
- if (fz && fz.click) {
529
- fz.click();
530
- }
531
- const cell = el.closest('.ms-DetailsRow-cell');
532
- if (cell && cell.focus) {
533
- cell.focus();
534
- }
535
- }
536
- if (column?.editable !== true) {
537
- (0, UITable_helper_1.showFocus)();
538
- }
539
- });
540
- if (rowIndex !== undefined && item && column && column.editable === true) {
541
- e?.stopPropagation();
542
- requestAnimationFrame(() => this.startEdit(rowIndex, item, column));
543
- }
544
- }
545
- /**
546
- * Validates passed value for cell and updates "errorMessage" property based on validation result.
547
- *
548
- * @param editedCell Cell to validate
549
- * @param value
550
- */
551
- validateCell(editedCell, value) {
552
- const column = editedCell?.column;
553
- let errorMessage = '';
554
- if (column && typeof column.validate === 'function') {
555
- errorMessage = column.validate(value);
556
- }
557
- if (editedCell && editedCell.errorMessage !== errorMessage) {
558
- if (typeof editedCell.rowIndex === 'number' && editedCell.column?.key) {
559
- const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
560
- const input = cell.querySelector('input');
561
- this.caretPosition = input.selectionStart || 0;
562
- }
563
- editedCell.errorMessage = errorMessage || undefined;
564
- // Rerender table to show error message
565
- this.rerenderTable();
566
- }
567
- }
568
- /**
569
- * On Text input change.
570
- *
571
- * @param e
572
- * @param newValue
573
- */
574
- onTextInputChange(e, newValue = '') {
575
- this.setState((prevState) => {
576
- const editedCell = prevState.editedCell ?? this.activeElement;
577
- if (editedCell) {
578
- editedCell.newValue = newValue;
579
- const column = editedCell.column;
580
- if (column && typeof column.validate === 'function') {
581
- this.validateCell(editedCell, newValue);
582
- }
583
- if (this.props.renderInputs) {
584
- this.saveCell(false, newValue);
585
- }
586
- }
587
- return { editedCell };
588
- });
589
- }
590
- /**
591
- * Gets input ref.
592
- *
593
- * @param rowIndex
594
- * @param column
595
- * @returns { React.RefObject<ITextField | IDropdown | HTMLDivElement> | undefined}
596
- */
597
- _getInputRef(rowIndex, column) {
598
- return typeof rowIndex === 'number' && typeof column?.key === 'string'
599
- ? this?.inputRefs?.[rowIndex]?.[column.key]
600
- : undefined;
601
- }
602
- /**
603
- * Renders dropdown.
604
- *
605
- * @param item
606
- * @param rowIndex
607
- * @param column
608
- * @returns {any}
609
- */
610
- _renderDropdown(item, rowIndex, column) {
611
- const compRef = this._getInputRef(rowIndex, column);
612
- return (react_1.default.createElement(UIDropdown_1.UIDropdown, { id: `dropdown_row${rowIndex}_col${column?.key}`, hidden: item.hideCells ?? false, placeholder: "Select an option", componentRef: compRef, options: column?.data.dropdownOptions, defaultSelectedKey: typeof column?.key === 'string' && item[column?.key]
613
- ? item[column?.key]
614
- : column?.data.defaultSelectedKey, onChange: (ev, text) => this.onDropdownCellValueChange(text, item, rowIndex, column), onKeyDown: this.onKeyDown }));
615
- }
616
- /**
617
- * Renders combobox.
618
- *
619
- * @param item
620
- * @param rowIndex
621
- * @param column
622
- * @returns {any}
623
- */
624
- _renderCombobox(item, rowIndex, column) {
625
- const compRef = this._getInputRef(rowIndex, column);
626
- const newValue = this.state.editedCell?.newValue;
627
- let value;
628
- if (column?.fieldName) {
629
- value = item[column?.fieldName];
630
- }
631
- if (typeof newValue !== 'undefined') {
632
- value = newValue;
633
- }
634
- const options = column?.comboboxOptions?.map((o) => ({ key: o, text: o })) || [];
635
- return (react_1.default.createElement(UIComboBox_1.UIComboBox, { highlight: true, defaultSelectedKey: value, allowFreeform: false, autoComplete: "on", shouldRestoreFocus: false, wrapperRef: compRef, errorMessage: this.state.editedCell?.errorMessage, openMenuOnClick: false, onPendingValueChanged: this.onComboBoxChange, onKeyDown: this.onKeyDown, onKeyDownCapture: this.onComboBoxKeyDownCapture, onClick: (e) => {
636
- e.stopPropagation();
637
- }, options: options }));
638
- }
639
- /**
640
- * Renders date picker.
641
- *
642
- * @param item
643
- * @param rowIndex
644
- * @param column
645
- * @param dateOnly
646
- * @returns {any}
647
- */
648
- _renderDatePicker(item, rowIndex, column, dateOnly = true) {
649
- const compRef = this._getInputRef(rowIndex, column);
650
- const newValue = this.state.editedCell?.newValue;
651
- let value;
652
- if (column?.fieldName) {
653
- value = item[column?.fieldName];
654
- }
655
- if (typeof newValue !== 'undefined') {
656
- value = newValue;
657
- }
658
- return (react_1.default.createElement(UIDatePicker_1.UIDatePicker, { defaultValue: value, componentRef: compRef, dateOnly: dateOnly, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
659
- e.stopPropagation();
660
- } }));
661
- }
662
- /**
663
- * Renders text input.
664
- *
665
- * @param item
666
- * @param rowIndex
667
- * @param column
668
- * @returns {any}
669
- */
670
- _renderTextInput(item, rowIndex, column) {
671
- const compRef = this._getInputRef(rowIndex, column);
672
- const newValue = this.state.editedCell?.newValue;
673
- let element;
674
- let value;
675
- if (column?.fieldName) {
676
- value = item[column?.fieldName];
677
- }
678
- if (typeof newValue !== 'undefined') {
679
- value = newValue;
680
- }
681
- if (!item.hideCells) {
682
- element = (react_1.default.createElement(UIInput_1.UITextInput, { defaultValue: value, componentRef: compRef, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
683
- e.stopPropagation();
684
- } }));
685
- }
686
- return element;
687
- }
688
- /**
689
- * On cell render.
690
- *
691
- * @param item
692
- * @param rowIndex
693
- * @param column
694
- * @returns {any}
695
- */
696
- _onCellRender(item, rowIndex, column) {
697
- // inputs & dropdowns always visible
698
- if (this.props.renderInputs && rowIndex !== undefined) {
699
- if (column?.columnControlType === types_1.ColumnControlType.UIDropdown) {
700
- return this._renderDropdown(item, rowIndex, column);
701
- }
702
- return this._renderTextInput(item, rowIndex, column);
703
- }
704
- // inputs visible only in "edit mode" (after cell click)
705
- const editedCell = this.state.editedCell;
706
- const itsThisRow = editedCell && editedCell.rowIndex === rowIndex;
707
- const itsThisCol = editedCell && editedCell.column?.key === column?.key;
708
- const isCellInEditMode = itsThisRow && itsThisCol;
709
- if (isCellInEditMode && rowIndex !== undefined) {
710
- if (column?.columnControlType === types_1.ColumnControlType.UICombobox) {
711
- return this._renderCombobox(item, rowIndex, column);
712
- }
713
- else if (column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
714
- return this._renderCombobox(item, rowIndex, { ...column, comboboxOptions: ['true', 'false'] });
715
- }
716
- else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
717
- return this._renderDatePicker(item, rowIndex, column, column?.type === 'Date');
718
- }
719
- else {
720
- return this._renderTextInput(item, rowIndex, column);
721
- }
722
- }
723
- const onClick = (e) => {
724
- e.stopPropagation();
725
- this._onCellClick(e, item, rowIndex || 0, column);
726
- };
727
- return (react_1.default.createElement("span", { style: { cursor: 'text', padding: 5 }, onClick: onClick }, item[column?.fieldName || 0]));
728
- }
729
- /**
730
- * @returns {JSX.Element}
731
- */
732
- render() {
733
- // get columns & items from props, so that detailsListProps does not contain them
734
- // because we want them to come from state, and be passed to component only once
735
- let { columns, items, checkboxVisibility, headerRenderer, selectionMode } = this.props;
736
- const { scrollablePaneProps, showRowNumbers, ...detailsListProps } = this.props;
737
- // get them from state if they exist
738
- if (this.state.columns) {
739
- columns = this.state.columns;
740
- }
741
- if (this.state.items) {
742
- items = this.state.items;
743
- }
744
- if (columns) {
745
- columns.forEach((col) => {
746
- col.onColumnClick = this._onColumnClick;
747
- if (col.editable === true) {
748
- col.onRender = this._onCellRender;
749
- }
750
- else {
751
- col.className = 'uneditable';
752
- }
753
- if (col.key === this.props.selectedColumnId) {
754
- col.headerClassName = 'selected';
755
- }
756
- });
757
- columns = (0, UITable_helper_1.addRowNumbers)(columns, showRowNumbers);
758
- }
759
- const styles = (0, UITable_helper_1.getStylesForSelectedCell)(this.state);
760
- if (typeof checkboxVisibility === 'undefined') {
761
- checkboxVisibility = react_2.CheckboxVisibility.hidden;
762
- }
763
- if (typeof selectionMode === 'undefined') {
764
- selectionMode = react_2.SelectionMode.single;
765
- }
766
- if (typeof headerRenderer === 'undefined') {
767
- headerRenderer = UITable_helper_1._onHeaderRender;
768
- }
769
- const focusZoneProps = {
770
- direction: react_2.FocusZoneDirection.vertical,
771
- shouldEnterInnerZone: (ev) => {
772
- return ev.key === 'ArrowRight';
773
- }
774
- };
775
- return (react_1.default.createElement(react_2.ScrollablePane, { ...scrollablePaneProps, styles: { stickyAbove: { zIndex: 2 } } },
776
- react_1.default.createElement(react_2.DetailsList, { checkboxVisibility: checkboxVisibility, componentRef: this.tableRef, selection: this.selection, selectionMode: selectionMode, onRenderCheckbox: this._onRenderCheckbox, onRenderDetailsHeader: headerRenderer, onRenderField: this._onRenderField, onRenderRow: this._onRenderRow, onRenderItemColumn: this._onRenderItemColumn, layoutMode: react_2.DetailsListLayoutMode.fixedColumns, constrainMode: react_2.ConstrainMode.unconstrained, focusZoneProps: focusZoneProps, onActiveItemChanged: this._onCellActivation, ...detailsListProps, items: items, columns: columns, styles: styles })));
777
- }
778
- }
779
- exports.UITable = UITable;
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.UITable = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_2 = require("@fluentui/react");
9
+ const UICheckbox_1 = require("../UICheckbox");
10
+ const UIInput_1 = require("../UIInput");
11
+ const UIDropdown_1 = require("../UIDropdown");
12
+ const UIComboBox_1 = require("../UIComboBox");
13
+ const UIDatePicker_1 = require("../UIDatePicker");
14
+ const UITable_helper_1 = require("./UITable-helper");
15
+ const types_1 = require("./types");
16
+ require("./UITable.scss");
17
+ /**
18
+ * UITable component
19
+ * based on: https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist
20
+ *
21
+ * @exports
22
+ * @class {UITable}
23
+ * @extends {React.Component<UITableProps, UITableState>}
24
+ */
25
+ class UITable extends react_1.default.Component {
26
+ /**
27
+ * Initializes component properties.
28
+ *
29
+ * @param props
30
+ */
31
+ constructor(props) {
32
+ super(props);
33
+ this.inputRefs = {};
34
+ this.activeElement = {};
35
+ this.caretPosition = -1;
36
+ this._onRenderRow = (props) => {
37
+ if (!props) {
38
+ return null;
39
+ }
40
+ const toggle = !!this.props.renderInputs;
41
+ return react_1.default.createElement(react_2.DetailsRow, { "data-selection-toggle": toggle, rowFieldsAs: this.renderRowFields.bind(this), ...props });
42
+ };
43
+ this.onComboBoxChange = (option) => {
44
+ this.setState((prevState) => {
45
+ const editedCell = prevState.editedCell ?? this.activeElement;
46
+ if (editedCell && option) {
47
+ editedCell.newValue = option.text;
48
+ }
49
+ return { editedCell };
50
+ });
51
+ };
52
+ this.onDropdownCellValueChange = (selectedOption, item, rowIndex, column) => {
53
+ const newValue = selectedOption.key;
54
+ if (typeof this.props.onSave === 'function' &&
55
+ typeof rowIndex === 'number' &&
56
+ Number.isInteger(rowIndex) &&
57
+ column) {
58
+ const currentValue = this.props.items[rowIndex][column.key];
59
+ const editedCell = { rowIndex, item, column, errorMessage: undefined };
60
+ if (currentValue !== newValue) {
61
+ this.props.onSave(editedCell, newValue);
62
+ }
63
+ const field = column?.fieldName;
64
+ if (field && item) {
65
+ item[field] = newValue;
66
+ }
67
+ }
68
+ this.cancelEdit();
69
+ };
70
+ this.state = {
71
+ columns: props.columns || [],
72
+ items: props.items || []
73
+ };
74
+ this.tableRef = react_1.default.createRef();
75
+ this.selection = new react_2.Selection({
76
+ onSelectionChanged: () => {
77
+ if (typeof this.props.onSelectionChange !== 'function') {
78
+ return;
79
+ }
80
+ this.props.onSelectionChange(this.selection.getSelectedIndices());
81
+ }
82
+ });
83
+ if (this.props.selectionRef) {
84
+ this.props.selectionRef.current = this.selection;
85
+ }
86
+ this.onTextInputChange = this.onTextInputChange.bind(this);
87
+ this.onComboBoxChange = this.onComboBoxChange.bind(this);
88
+ this.onDocumentMousedown = this.onDocumentMousedown.bind(this);
89
+ this.onKeyDown = this.onKeyDown.bind(this);
90
+ this.onComboBoxKeyDownCapture = this.onComboBoxKeyDownCapture.bind(this);
91
+ this.validateCell = this.validateCell.bind(this);
92
+ this.editNextCell = this.editNextCell.bind(this);
93
+ this._onColumnClick = this._onColumnClick.bind(this);
94
+ this._onCellRender = this._onCellRender.bind(this);
95
+ this._onRenderCheckbox = this._onRenderCheckbox.bind(this);
96
+ this._onRenderField = this._onRenderField?.bind(this);
97
+ this._onRenderRow = this._onRenderRow?.bind(this);
98
+ this._onRenderItemColumn = this._onRenderItemColumn?.bind(this);
99
+ this._onCellActivation = this._onCellActivation?.bind(this);
100
+ }
101
+ componentDidMount() {
102
+ this.onDocMousedown = this.onDocumentMousedown;
103
+ document.addEventListener('mousedown', this.onDocMousedown, true);
104
+ window.dispatchEvent(new Event('resize'));
105
+ this._setTextRefs();
106
+ }
107
+ componentWillUnmount() {
108
+ document.removeEventListener('mousedown', this.onDocMousedown);
109
+ }
110
+ /**
111
+ * On component update.
112
+ *
113
+ * @param prevProps
114
+ * @param prevState
115
+ */
116
+ componentDidUpdate(prevProps, prevState) {
117
+ const scrollContainer = document.querySelector('.ms-ScrollablePane--contentContainer');
118
+ if (scrollContainer) {
119
+ const left = scrollContainer.scrollLeft || 0;
120
+ requestAnimationFrame(() => (scrollContainer.scrollLeft = left));
121
+ }
122
+ if (prevProps.items !== this.props.items) {
123
+ this.setState({ items: this.props.items });
124
+ this._setTextRefs();
125
+ }
126
+ if (prevProps.columns !== this.props.columns) {
127
+ this.setState({ columns: this.props.columns });
128
+ }
129
+ if (prevProps.dataSetKey !== this.props.dataSetKey) {
130
+ this.setState({ editedCell: undefined });
131
+ }
132
+ if (typeof this.props.selectedRow !== 'undefined' && prevProps.selectedRow !== this.props.selectedRow) {
133
+ (0, UITable_helper_1.scrollToRow)(this.props.selectedRow, this.tableRef?.current);
134
+ }
135
+ if (this.props.scrollToAddedRow) {
136
+ const dataSetChanged = this.props.dataSetKey !== prevProps.dataSetKey;
137
+ const { items } = this.state;
138
+ const { items: prevItems } = prevState;
139
+ const itemsDelta = items.length - prevItems.length;
140
+ const shouldScrollToNewRow = !dataSetChanged && itemsDelta === 1;
141
+ if (shouldScrollToNewRow && this.tableRef && this.tableRef.current) {
142
+ const newRowIndex = items.length - 1;
143
+ this.tableRef.current.scrollToIndex(newRowIndex);
144
+ }
145
+ }
146
+ const { selectedColumnId } = this.props;
147
+ const { selectedColumnId: prevSelectedColumnId } = prevProps;
148
+ // Due to table rendering using columns data from state, instead of props,
149
+ // to sync selected column change callback with rendered dataset change
150
+ // selected column id/key needs to be stored on a state level along with columns data
151
+ if (selectedColumnId !== prevSelectedColumnId) {
152
+ this.setState({ selectedColumnId });
153
+ }
154
+ const columnIsSelected = typeof this.state.selectedColumnId !== 'undefined';
155
+ const selectedColumnDidChange = prevState.selectedColumnId !== this.state.selectedColumnId;
156
+ if (columnIsSelected && selectedColumnDidChange) {
157
+ (0, UITable_helper_1.scrollToColumn)(this.state.selectedColumnId || '', this.state.columns, this.props.selectedRow || 0, this.props.showRowNumbers);
158
+ }
159
+ this._restoreCaretPosition();
160
+ }
161
+ /**
162
+ * Restores the caret position. Caret position gets lost when validation finds issue in cell.
163
+ */
164
+ _restoreCaretPosition() {
165
+ const editedCell = this.state.editedCell;
166
+ if (this.caretPosition !== -1 && typeof editedCell?.rowIndex === 'number' && editedCell.column?.key) {
167
+ const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
168
+ const input = cell.querySelector('input');
169
+ if (input && input.selectionStart !== this.caretPosition) {
170
+ input.setSelectionRange(this.caretPosition, this.caretPosition);
171
+ this.caretPosition = -1;
172
+ }
173
+ }
174
+ }
175
+ _setTextRefs() {
176
+ if (this.props.columns && this.props.items) {
177
+ for (const rowIndexTmp in this.props.items) {
178
+ for (const col of this.props.columns) {
179
+ if (col.editable === true && this.inputRefs) {
180
+ this.inputRefs[rowIndexTmp] = this.inputRefs[rowIndexTmp] || {};
181
+ this.inputRefs[rowIndexTmp][col.key] = react_1.default.createRef();
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ /**
188
+ * On render row fields event.
189
+ *
190
+ * @param props
191
+ * @returns {JSX.Element}
192
+ */
193
+ renderRowFields(props) {
194
+ // disabled is set to false when selectionMode === undefined || selectionMode === SelectionMode.single
195
+ let disabled = false;
196
+ const selectionMode = this.props.selectionMode;
197
+ if (selectionMode === react_2.SelectionMode.multiple || selectionMode === react_2.SelectionMode.none) {
198
+ disabled = true;
199
+ }
200
+ return (react_1.default.createElement("div", { "data-selection-disabled": disabled },
201
+ react_1.default.createElement(react_2.DetailsRowFields, { ...props })));
202
+ }
203
+ /**
204
+ * On render field event.
205
+ *
206
+ * @param props
207
+ * @param defaultRender
208
+ * @returns {null | JSX.Element}
209
+ */
210
+ _onRenderField(props, defaultRender) {
211
+ if (!props || !defaultRender) {
212
+ return null;
213
+ }
214
+ const cell = defaultRender(props);
215
+ const onClick = (e) => {
216
+ const target = e?.target;
217
+ const targetTag = target?.tagName;
218
+ if (['INPUT', 'TEXTAREA', 'SELECT'].includes(targetTag)) {
219
+ return;
220
+ }
221
+ const { item, rowIndex, column } = this.activeElement;
222
+ this._onCellClick(e, item, rowIndex || 0, column);
223
+ };
224
+ // in app-migrator, show a warning message for library projects on main migration view
225
+ if (props.item.hideCells && props.column.fieldName === 'moduleName' && !props.item.status) {
226
+ return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" },
227
+ cell?.props?.children || null,
228
+ react_1.default.createElement("div", { className: "table-item-warning" }, "This is a reuse library and does not require input during migration")));
229
+ }
230
+ else {
231
+ return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" }, cell?.props?.children || null));
232
+ }
233
+ }
234
+ // just sets the active element property on the table, to track it later
235
+ /**
236
+ * On cell activation event.
237
+ *
238
+ * @param item
239
+ * @param rowIndex
240
+ * @param ev
241
+ */
242
+ _onCellActivation(item, rowIndex, ev) {
243
+ const rowEl = ev?.target?.closest('.ms-DetailsRow');
244
+ let column = {};
245
+ const cells = rowEl?.querySelectorAll('.ms-DetailsRow-fields .ms-DetailsRow-cell');
246
+ if (!cells || !cells.length) {
247
+ return;
248
+ }
249
+ // focusing cell, not the row
250
+ const cellEl = ev?.target?.closest('.ms-DetailsRow-cell');
251
+ if (cellEl) {
252
+ const cellIdx = Array.from(cells).indexOf(cellEl);
253
+ if (cellIdx === -1) {
254
+ return;
255
+ }
256
+ column = this.props.columns[cellIdx];
257
+ if (!column) {
258
+ return;
259
+ }
260
+ }
261
+ this.activeElement = { item, rowIndex: rowIndex || 0, column };
262
+ if (this.props.renderInputs && column?.editable) {
263
+ const isDropdown = this.activeElement?.column?.columnControlType === types_1.ColumnControlType?.UIDropdown;
264
+ if (!isDropdown && this.state.editedCell?.column?.key !== this.activeElement?.column?.key) {
265
+ this.setState({ editedCell: this.activeElement });
266
+ }
267
+ }
268
+ }
269
+ /**
270
+ * On render item column event.
271
+ *
272
+ * @param {UIDocument} item
273
+ * @param {number} index
274
+ * @param {UIColumn} column
275
+ * @returns {React.ReactNode}
276
+ */
277
+ _onRenderItemColumn(item, index, column) {
278
+ if (column?.key === '__row_number__') {
279
+ return react_1.default.createElement("div", { className: "ms-DetailsList-row-number" }, (index || 0) + 1);
280
+ }
281
+ return item[column?.fieldName || ''] || '';
282
+ }
283
+ // Replace weird radio-button-checkboxes with proper checkboxes
284
+ /**
285
+ * On render checkbox event.
286
+ *
287
+ * @param {IDetailsListCheckboxProps | undefined} props
288
+ * @returns {React.ReactElement}
289
+ */
290
+ _onRenderCheckbox(props) {
291
+ return react_1.default.createElement(UICheckbox_1.UICheckbox, { ...props });
292
+ }
293
+ // COLUMN HEADER SORT
294
+ /**
295
+ * On column click event.
296
+ *
297
+ * @param ev
298
+ * @param column
299
+ */
300
+ _onColumnClick(ev, column) {
301
+ const { columns, items } = this.state;
302
+ const newColumns = columns.slice();
303
+ const currColumn = newColumns.filter((currCol) => column.key === currCol.key)[0];
304
+ newColumns.forEach((newCol) => {
305
+ if (newCol === currColumn) {
306
+ currColumn.isSortedDescending = !currColumn.isSortedDescending;
307
+ currColumn.isSorted = true;
308
+ }
309
+ else {
310
+ newCol.isSorted = false;
311
+ newCol.isSortedDescending = false;
312
+ }
313
+ });
314
+ const field = currColumn.fieldName || currColumn.name || '';
315
+ const newItems = (0, UITable_helper_1._copyAndSort)(items, field, currColumn.isSortedDescending);
316
+ this.setState({ columns: newColumns, items: newItems });
317
+ }
318
+ // CELL EDITING
319
+ /**
320
+ * On start edit event call.
321
+ *
322
+ * @param rowIndex
323
+ * @param item
324
+ * @param column
325
+ * @param errorMessage
326
+ */
327
+ startEdit(rowIndex, item, column, errorMessage) {
328
+ const { editedCell } = this.state;
329
+ const isAlreadyInEdit = editedCell?.rowIndex === rowIndex && column?.key && editedCell?.column?.key === column?.key;
330
+ if (!isAlreadyInEdit) {
331
+ this.setState({ editedCell: { rowIndex, item, column, errorMessage } });
332
+ if (!this.props.renderInputs) {
333
+ this.rerenderTable();
334
+ }
335
+ }
336
+ requestAnimationFrame(() => {
337
+ if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
338
+ this.inputRefs?.[rowIndex][column?.key]?.current?.select();
339
+ }
340
+ else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
341
+ column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
342
+ const combo = this.inputRefs?.[rowIndex][column?.key];
343
+ (0, UITable_helper_1.getComboBoxInput)(combo)?.focus();
344
+ }
345
+ else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
346
+ this.inputRefs?.[rowIndex][column?.key]?.current?.select();
347
+ }
348
+ else if (column?.key) {
349
+ const otherElement = this.inputRefs?.[rowIndex][column.key]?.current;
350
+ otherElement.focus();
351
+ }
352
+ });
353
+ }
354
+ rerenderTable() {
355
+ if (this.tableRef.current) {
356
+ this.tableRef.current.forceUpdate();
357
+ }
358
+ }
359
+ cancelEdit() {
360
+ this.caretPosition = -1;
361
+ this.setState({ editedCell: undefined });
362
+ this.rerenderTable();
363
+ }
364
+ /**
365
+ * On save cell event.
366
+ *
367
+ * @param cancelEdit
368
+ * @param value
369
+ */
370
+ saveCell(cancelEdit = false, value) {
371
+ this.caretPosition = -1;
372
+ if (typeof this.props.onSave === 'function' && this.state.editedCell) {
373
+ const { rowIndex, column } = this.state.editedCell;
374
+ if (column?.columnControlType !== types_1.ColumnControlType.UIDropdown && !this.state.editedCell.errorMessage) {
375
+ let compRef;
376
+ if (column && this?.inputRefs?.[rowIndex]?.[column.key]) {
377
+ compRef = this?.inputRefs[rowIndex][column.key];
378
+ }
379
+ const currentValue = column && this.props.items[rowIndex][column.key];
380
+ let refValue = '';
381
+ if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
382
+ refValue = compRef?.current?.value || '';
383
+ }
384
+ else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
385
+ refValue = compRef?.current?.value || '';
386
+ }
387
+ else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
388
+ column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
389
+ const combo = compRef;
390
+ refValue = (0, UITable_helper_1.getComboBoxInput)(combo)?.value || '';
391
+ }
392
+ const newValue = value ?? refValue;
393
+ if (currentValue !== newValue) {
394
+ this.props.onSave(this.state.editedCell, newValue);
395
+ }
396
+ const item = this.state.editedCell?.item;
397
+ const field = column?.fieldName;
398
+ if (field && item) {
399
+ item[field] = newValue;
400
+ }
401
+ }
402
+ }
403
+ if (cancelEdit) {
404
+ this.cancelEdit();
405
+ }
406
+ }
407
+ /**
408
+ * On mouse down event.
409
+ *
410
+ * @param e
411
+ */
412
+ onDocumentMousedown(e) {
413
+ const target = e.target; // needed for TSC
414
+ if (target.closest('.ms-TextField, .ms-ComboBox, .ms-ComboBox-option, .ui-DatePicker') &&
415
+ !this.props.renderInputs) {
416
+ return;
417
+ }
418
+ if (this.state.editedCell) {
419
+ if (this.state.editedCell.errorMessage) {
420
+ e.preventDefault();
421
+ }
422
+ else {
423
+ this.saveCell(true);
424
+ }
425
+ }
426
+ }
427
+ /**
428
+ * On key down event.
429
+ *
430
+ * @param {React.KeyboardEvent<Element | IDropdown>} e
431
+ * @returns {void}
432
+ */
433
+ onKeyDown(e) {
434
+ if (!['Enter', 'Tab', 'Escape', 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
435
+ return;
436
+ }
437
+ const isArrow = ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key);
438
+ const isInput = e.target.tagName === 'INPUT';
439
+ if (isArrow && isInput) {
440
+ e.stopPropagation();
441
+ return;
442
+ }
443
+ e.preventDefault();
444
+ if (e.key === 'Escape') {
445
+ this.cancelEdit();
446
+ (0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props).catch(() => {
447
+ // Ignore focus cell error
448
+ });
449
+ (0, UITable_helper_1.showFocus)();
450
+ return;
451
+ }
452
+ if (this.state.editedCell?.errorMessage) {
453
+ return;
454
+ }
455
+ e.stopPropagation();
456
+ if (e.key === 'Enter' || e.key === 'Tab') {
457
+ this.editNextCell(e.key, e.shiftKey);
458
+ }
459
+ }
460
+ /**
461
+ * On ComboBox keydown event call.
462
+ *
463
+ * @param e
464
+ */
465
+ onComboBoxKeyDownCapture(e) {
466
+ if (e.key === 'Enter' || e.key === 'Tab') {
467
+ // stop Enter from opening combobox
468
+ e.stopPropagation();
469
+ e.preventDefault();
470
+ this.editNextCell(e.key, e.shiftKey);
471
+ }
472
+ }
473
+ /**
474
+ * On Edit next cell.
475
+ *
476
+ * @param key
477
+ * @param shiftKey
478
+ */
479
+ editNextCell(key, shiftKey) {
480
+ this.saveCell();
481
+ let direction = '';
482
+ if (key === 'Enter') {
483
+ direction = shiftKey ? 'up' : 'down';
484
+ }
485
+ else if (key === 'Tab') {
486
+ direction = shiftKey ? 'left' : 'right';
487
+ }
488
+ if (direction) {
489
+ (0, UITable_helper_1.hideFocus)();
490
+ }
491
+ setTimeout(() => {
492
+ (0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props, direction)
493
+ .then(() => {
494
+ if (!direction) {
495
+ (0, UITable_helper_1.showFocus)();
496
+ return;
497
+ }
498
+ (0, UITable_helper_1.hideFocus)();
499
+ const { rowIndex, item, column } = this.activeElement;
500
+ this.startEdit(rowIndex, item, column);
501
+ })
502
+ .catch((e) => {
503
+ throw e;
504
+ });
505
+ }, 100);
506
+ }
507
+ /**
508
+ * On Cell click.
509
+ *
510
+ * @param e
511
+ * @param item
512
+ * @param rowIndex
513
+ * @param column
514
+ */
515
+ _onCellClick(e, item, rowIndex, column) {
516
+ const previousCellHasErrors = this.state.editedCell?.errorMessage;
517
+ if (previousCellHasErrors) {
518
+ return;
519
+ }
520
+ if (this.props.renderInputs) {
521
+ return;
522
+ }
523
+ const el = e?.target;
524
+ requestAnimationFrame(() => {
525
+ // check the checkbox & focus the clicked cell
526
+ if (el) {
527
+ const fz = el.closest('.ms-FocusZone');
528
+ if (fz && fz.click) {
529
+ fz.click();
530
+ }
531
+ const cell = el.closest('.ms-DetailsRow-cell');
532
+ if (cell && cell.focus) {
533
+ cell.focus();
534
+ }
535
+ }
536
+ if (column?.editable !== true) {
537
+ (0, UITable_helper_1.showFocus)();
538
+ }
539
+ });
540
+ if (rowIndex !== undefined && item && column && column.editable === true) {
541
+ e?.stopPropagation();
542
+ requestAnimationFrame(() => this.startEdit(rowIndex, item, column));
543
+ }
544
+ }
545
+ /**
546
+ * Validates passed value for cell and updates "errorMessage" property based on validation result.
547
+ *
548
+ * @param editedCell Cell to validate
549
+ * @param value
550
+ */
551
+ validateCell(editedCell, value) {
552
+ const column = editedCell?.column;
553
+ let errorMessage = '';
554
+ if (column && typeof column.validate === 'function') {
555
+ errorMessage = column.validate(value);
556
+ }
557
+ if (editedCell && editedCell.errorMessage !== errorMessage) {
558
+ if (typeof editedCell.rowIndex === 'number' && editedCell.column?.key) {
559
+ const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
560
+ const input = cell.querySelector('input');
561
+ this.caretPosition = input.selectionStart || 0;
562
+ }
563
+ editedCell.errorMessage = errorMessage || undefined;
564
+ // Rerender table to show error message
565
+ this.rerenderTable();
566
+ }
567
+ }
568
+ /**
569
+ * On Text input change.
570
+ *
571
+ * @param e
572
+ * @param newValue
573
+ */
574
+ onTextInputChange(e, newValue = '') {
575
+ this.setState((prevState) => {
576
+ const editedCell = prevState.editedCell ?? this.activeElement;
577
+ if (editedCell) {
578
+ editedCell.newValue = newValue;
579
+ const column = editedCell.column;
580
+ if (column && typeof column.validate === 'function') {
581
+ this.validateCell(editedCell, newValue);
582
+ }
583
+ if (this.props.renderInputs) {
584
+ this.saveCell(false, newValue);
585
+ }
586
+ }
587
+ return { editedCell };
588
+ });
589
+ }
590
+ /**
591
+ * Gets input ref.
592
+ *
593
+ * @param rowIndex
594
+ * @param column
595
+ * @returns { React.RefObject<ITextField | IDropdown | HTMLDivElement> | undefined}
596
+ */
597
+ _getInputRef(rowIndex, column) {
598
+ return typeof rowIndex === 'number' && typeof column?.key === 'string'
599
+ ? this?.inputRefs?.[rowIndex]?.[column.key]
600
+ : undefined;
601
+ }
602
+ /**
603
+ * Renders dropdown.
604
+ *
605
+ * @param item
606
+ * @param rowIndex
607
+ * @param column
608
+ * @returns {any}
609
+ */
610
+ _renderDropdown(item, rowIndex, column) {
611
+ const compRef = this._getInputRef(rowIndex, column);
612
+ return (react_1.default.createElement(UIDropdown_1.UIDropdown, { id: `dropdown_row${rowIndex}_col${column?.key}`, hidden: item.hideCells ?? false, placeholder: "Select an option", componentRef: compRef, options: column?.data.dropdownOptions, defaultSelectedKey: typeof column?.key === 'string' && item[column?.key]
613
+ ? item[column?.key]
614
+ : column?.data.defaultSelectedKey, onChange: (ev, text) => this.onDropdownCellValueChange(text, item, rowIndex, column), onKeyDown: this.onKeyDown }));
615
+ }
616
+ /**
617
+ * Renders combobox.
618
+ *
619
+ * @param item
620
+ * @param rowIndex
621
+ * @param column
622
+ * @returns {any}
623
+ */
624
+ _renderCombobox(item, rowIndex, column) {
625
+ const compRef = this._getInputRef(rowIndex, column);
626
+ const newValue = this.state.editedCell?.newValue;
627
+ let value;
628
+ if (column?.fieldName) {
629
+ value = item[column?.fieldName];
630
+ }
631
+ if (typeof newValue !== 'undefined') {
632
+ value = newValue;
633
+ }
634
+ const options = column?.comboboxOptions?.map((o) => ({ key: o, text: o })) || [];
635
+ return (react_1.default.createElement(UIComboBox_1.UIComboBox, { highlight: true, defaultSelectedKey: value, allowFreeform: false, autoComplete: "on", shouldRestoreFocus: false, wrapperRef: compRef, errorMessage: this.state.editedCell?.errorMessage, openMenuOnClick: false, onPendingValueChanged: this.onComboBoxChange, onKeyDown: this.onKeyDown, onKeyDownCapture: this.onComboBoxKeyDownCapture, onClick: (e) => {
636
+ e.stopPropagation();
637
+ }, options: options }));
638
+ }
639
+ /**
640
+ * Renders date picker.
641
+ *
642
+ * @param item
643
+ * @param rowIndex
644
+ * @param column
645
+ * @param dateOnly
646
+ * @returns {any}
647
+ */
648
+ _renderDatePicker(item, rowIndex, column, dateOnly = true) {
649
+ const compRef = this._getInputRef(rowIndex, column);
650
+ const newValue = this.state.editedCell?.newValue;
651
+ let value;
652
+ if (column?.fieldName) {
653
+ value = item[column?.fieldName];
654
+ }
655
+ if (typeof newValue !== 'undefined') {
656
+ value = newValue;
657
+ }
658
+ return (react_1.default.createElement(UIDatePicker_1.UIDatePicker, { defaultValue: value, componentRef: compRef, dateOnly: dateOnly, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
659
+ e.stopPropagation();
660
+ } }));
661
+ }
662
+ /**
663
+ * Renders text input.
664
+ *
665
+ * @param item
666
+ * @param rowIndex
667
+ * @param column
668
+ * @returns {any}
669
+ */
670
+ _renderTextInput(item, rowIndex, column) {
671
+ const compRef = this._getInputRef(rowIndex, column);
672
+ const newValue = this.state.editedCell?.newValue;
673
+ let element;
674
+ let value;
675
+ if (column?.fieldName) {
676
+ value = item[column?.fieldName];
677
+ }
678
+ if (typeof newValue !== 'undefined') {
679
+ value = newValue;
680
+ }
681
+ if (!item.hideCells) {
682
+ element = (react_1.default.createElement(UIInput_1.UITextInput, { defaultValue: value, componentRef: compRef, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
683
+ e.stopPropagation();
684
+ } }));
685
+ }
686
+ return element;
687
+ }
688
+ /**
689
+ * On cell render.
690
+ *
691
+ * @param item
692
+ * @param rowIndex
693
+ * @param column
694
+ * @returns {any}
695
+ */
696
+ _onCellRender(item, rowIndex, column) {
697
+ // inputs & dropdowns always visible
698
+ if (this.props.renderInputs && rowIndex !== undefined) {
699
+ if (column?.columnControlType === types_1.ColumnControlType.UIDropdown) {
700
+ return this._renderDropdown(item, rowIndex, column);
701
+ }
702
+ return this._renderTextInput(item, rowIndex, column);
703
+ }
704
+ // inputs visible only in "edit mode" (after cell click)
705
+ const editedCell = this.state.editedCell;
706
+ const itsThisRow = editedCell && editedCell.rowIndex === rowIndex;
707
+ const itsThisCol = editedCell && editedCell.column?.key === column?.key;
708
+ const isCellInEditMode = itsThisRow && itsThisCol;
709
+ if (isCellInEditMode && rowIndex !== undefined) {
710
+ if (column?.columnControlType === types_1.ColumnControlType.UICombobox) {
711
+ return this._renderCombobox(item, rowIndex, column);
712
+ }
713
+ else if (column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
714
+ return this._renderCombobox(item, rowIndex, { ...column, comboboxOptions: ['true', 'false'] });
715
+ }
716
+ else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
717
+ return this._renderDatePicker(item, rowIndex, column, column?.type === 'Date');
718
+ }
719
+ else {
720
+ return this._renderTextInput(item, rowIndex, column);
721
+ }
722
+ }
723
+ const onClick = (e) => {
724
+ e.stopPropagation();
725
+ this._onCellClick(e, item, rowIndex || 0, column);
726
+ };
727
+ return (react_1.default.createElement("span", { style: { cursor: 'text', padding: 5 }, onClick: onClick }, item[column?.fieldName || 0]));
728
+ }
729
+ /**
730
+ * @returns {JSX.Element}
731
+ */
732
+ render() {
733
+ // get columns & items from props, so that detailsListProps does not contain them
734
+ // because we want them to come from state, and be passed to component only once
735
+ let { columns, items, checkboxVisibility, headerRenderer, selectionMode } = this.props;
736
+ const { scrollablePaneProps, showRowNumbers, ...detailsListProps } = this.props;
737
+ // get them from state if they exist
738
+ if (this.state.columns) {
739
+ columns = this.state.columns;
740
+ }
741
+ if (this.state.items) {
742
+ items = this.state.items;
743
+ }
744
+ if (columns) {
745
+ columns.forEach((col) => {
746
+ col.onColumnClick = this._onColumnClick;
747
+ if (col.editable === true) {
748
+ col.onRender = this._onCellRender;
749
+ }
750
+ else {
751
+ col.className = 'uneditable';
752
+ }
753
+ if (col.key === this.props.selectedColumnId) {
754
+ col.headerClassName = 'selected';
755
+ }
756
+ });
757
+ columns = (0, UITable_helper_1.addRowNumbers)(columns, showRowNumbers);
758
+ }
759
+ const styles = (0, UITable_helper_1.getStylesForSelectedCell)(this.state);
760
+ if (typeof checkboxVisibility === 'undefined') {
761
+ checkboxVisibility = react_2.CheckboxVisibility.hidden;
762
+ }
763
+ if (typeof selectionMode === 'undefined') {
764
+ selectionMode = react_2.SelectionMode.single;
765
+ }
766
+ if (typeof headerRenderer === 'undefined') {
767
+ headerRenderer = UITable_helper_1._onHeaderRender;
768
+ }
769
+ const focusZoneProps = {
770
+ direction: react_2.FocusZoneDirection.vertical,
771
+ shouldEnterInnerZone: (ev) => {
772
+ return ev.key === 'ArrowRight';
773
+ }
774
+ };
775
+ return (react_1.default.createElement(react_2.ScrollablePane, { ...scrollablePaneProps, styles: { stickyAbove: { zIndex: 2 } } },
776
+ react_1.default.createElement(react_2.DetailsList, { checkboxVisibility: checkboxVisibility, componentRef: this.tableRef, selection: this.selection, selectionMode: selectionMode, onRenderCheckbox: this._onRenderCheckbox, onRenderDetailsHeader: headerRenderer, onRenderField: this._onRenderField, onRenderRow: this._onRenderRow, onRenderItemColumn: this._onRenderItemColumn, layoutMode: react_2.DetailsListLayoutMode.fixedColumns, constrainMode: react_2.ConstrainMode.unconstrained, focusZoneProps: focusZoneProps, onActiveItemChanged: this._onCellActivation, ...detailsListProps, items: items, columns: columns, styles: styles })));
777
+ }
778
+ }
779
+ exports.UITable = UITable;
780
780
  //# sourceMappingURL=UITable.js.map