@openui5/sap.f 1.108.1 → 1.109.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 (91) hide show
  1. package/THIRDPARTY.txt +1 -1
  2. package/package.json +4 -4
  3. package/src/sap/f/.library +1 -1
  4. package/src/sap/f/Avatar.js +1 -1
  5. package/src/sap/f/AvatarGroup.js +1 -1
  6. package/src/sap/f/AvatarGroupItem.js +1 -1
  7. package/src/sap/f/AvatarGroupRenderer.js +2 -5
  8. package/src/sap/f/CalendarAppointmentInCard.js +1 -1
  9. package/src/sap/f/CalendarInCard.js +1 -1
  10. package/src/sap/f/Card.js +1 -1
  11. package/src/sap/f/CardBase.js +1 -1
  12. package/src/sap/f/DynamicPage.js +2 -1
  13. package/src/sap/f/DynamicPageAccessibleLandmarkInfo.js +1 -1
  14. package/src/sap/f/DynamicPageHeader.js +2 -2
  15. package/src/sap/f/DynamicPageTitle.js +2 -2
  16. package/src/sap/f/FlexibleColumnLayout.js +1 -1
  17. package/src/sap/f/FlexibleColumnLayoutAccessibleLandmarkInfo.js +1 -1
  18. package/src/sap/f/FlexibleColumnLayoutSemanticHelper.js +1 -1
  19. package/src/sap/f/GridContainer.js +1 -1
  20. package/src/sap/f/GridContainerItemLayoutData.js +1 -1
  21. package/src/sap/f/GridContainerRenderer.js +1 -1
  22. package/src/sap/f/GridContainerSettings.js +2 -2
  23. package/src/sap/f/GridContainerUtils.js +4 -4
  24. package/src/sap/f/GridList.js +1 -1
  25. package/src/sap/f/GridListItem.js +1 -1
  26. package/src/sap/f/GridNavigationMatrix.js +2 -2
  27. package/src/sap/f/IllustratedMessage.js +1 -1
  28. package/src/sap/f/Illustration.js +1 -1
  29. package/src/sap/f/PlanningCalendarInCardLegend.js +1 -1
  30. package/src/sap/f/ProductSwitch.js +1 -49
  31. package/src/sap/f/ProductSwitchItem.js +1 -1
  32. package/src/sap/f/ProductSwitchItemRenderer.js +0 -1
  33. package/src/sap/f/SearchManager.js +1 -1
  34. package/src/sap/f/ShellBar.js +1 -1
  35. package/src/sap/f/SidePanel.js +391 -84
  36. package/src/sap/f/SidePanelItem.js +1 -2
  37. package/src/sap/f/SidePanelRenderer.js +62 -19
  38. package/src/sap/f/cards/BaseHeader.js +10 -12
  39. package/src/sap/f/cards/Header.js +1 -1
  40. package/src/sap/f/cards/HeaderRenderer.js +1 -1
  41. package/src/sap/f/cards/NumericHeader.js +10 -2
  42. package/src/sap/f/cards/NumericIndicators.js +10 -2
  43. package/src/sap/f/cards/NumericIndicatorsRenderer.js +6 -3
  44. package/src/sap/f/cards/NumericSideIndicator.js +1 -1
  45. package/src/sap/f/cards/loading/AnalyticalPlaceholder.js +1 -1
  46. package/src/sap/f/cards/loading/CalendarPlaceholder.js +4 -5
  47. package/src/sap/f/cards/loading/GenericPlaceholder.js +1 -1
  48. package/src/sap/f/cards/loading/ListPlaceholder.js +5 -5
  49. package/src/sap/f/cards/loading/ObjectPlaceholder.js +1 -1
  50. package/src/sap/f/cards/loading/TablePlaceholder.js +5 -5
  51. package/src/sap/f/cards/loading/TimelinePlaceholder.js +6 -6
  52. package/src/sap/f/changeHandler/MoveDynamicPageTitleActions.js +1 -1
  53. package/src/sap/f/delegate/GridContainerItemNavigation.js +19 -41
  54. package/src/sap/f/delegate/GridItemNavigation.js +7 -17
  55. package/src/sap/f/dnd/GridDragOver.js +10 -4
  56. package/src/sap/f/dnd/GridDropInfo.js +1 -1
  57. package/src/sap/f/library.js +2 -2
  58. package/src/sap/f/messagebundle.properties +11 -0
  59. package/src/sap/f/messagebundle_en_US_saprigi.properties +7 -0
  60. package/src/sap/f/semantic/AddAction.js +1 -1
  61. package/src/sap/f/semantic/CloseAction.js +1 -1
  62. package/src/sap/f/semantic/CopyAction.js +1 -1
  63. package/src/sap/f/semantic/DeleteAction.js +1 -1
  64. package/src/sap/f/semantic/DiscussInJamAction.js +1 -1
  65. package/src/sap/f/semantic/EditAction.js +1 -1
  66. package/src/sap/f/semantic/ExitFullScreenAction.js +1 -1
  67. package/src/sap/f/semantic/FavoriteAction.js +1 -1
  68. package/src/sap/f/semantic/FlagAction.js +1 -1
  69. package/src/sap/f/semantic/FooterMainAction.js +1 -1
  70. package/src/sap/f/semantic/FullScreenAction.js +1 -1
  71. package/src/sap/f/semantic/MainAction.js +1 -1
  72. package/src/sap/f/semantic/MessagesIndicator.js +1 -1
  73. package/src/sap/f/semantic/NegativeAction.js +1 -1
  74. package/src/sap/f/semantic/PositiveAction.js +1 -1
  75. package/src/sap/f/semantic/PrintAction.js +1 -1
  76. package/src/sap/f/semantic/SemanticButton.js +1 -1
  77. package/src/sap/f/semantic/SemanticConfiguration.js +3 -7
  78. package/src/sap/f/semantic/SemanticControl.js +1 -1
  79. package/src/sap/f/semantic/SemanticPage.js +1 -1
  80. package/src/sap/f/semantic/SemanticToggleButton.js +1 -1
  81. package/src/sap/f/semantic/SendEmailAction.js +1 -1
  82. package/src/sap/f/semantic/SendMessageAction.js +1 -1
  83. package/src/sap/f/semantic/ShareInJamAction.js +1 -1
  84. package/src/sap/f/semantic/TitleMainAction.js +1 -1
  85. package/src/sap/f/shellBar/AdditionalContentSupport.js +1 -1
  86. package/src/sap/f/shellBar/CoPilot.js +1 -1
  87. package/src/sap/f/shellBar/CoPilotRenderer.js +11 -6
  88. package/src/sap/f/shellBar/ControlSpacer.js +1 -1
  89. package/src/sap/f/shellBar/Search.js +1 -1
  90. package/src/sap/f/themes/base/GridList.less +4 -0
  91. package/src/sap/f/themes/base/SidePanel.less +189 -29
@@ -52,6 +52,17 @@ sap.ui.define([
52
52
  var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.f"),
53
53
  InvisibleMessageMode = coreLibrary.InvisibleMessageMode;
54
54
 
55
+ // Resize positions
56
+ var SIDE_PANEL_POSITION_MIN_WIDTH = 0, // Minimum width
57
+ SIDE_PANEL_POSITION_INITIAL = 1, // Initial width
58
+ SIDE_PANEL_POSITION_MAX_WIDTH = 2; // Maximum width
59
+
60
+ // Split breakpoint
61
+ var SIDE_PANEL_SPLIT_BREAKPOINT = 560;
62
+ // When there is an action item chosen and the width of the expanded side panel is less or equal to this value,
63
+ // the expanded action bar takes the whole width and hides the side content, otherwise the action bar takes
64
+ // 20rem (its default width), and the rest of the side panel width is taken by the expanded side content.
65
+
55
66
  /**
56
67
  * Constructor for a new <code>SidePanel</code>.
57
68
  *
@@ -63,14 +74,14 @@ sap.ui.define([
63
74
  * <h3>Overview</h3>
64
75
  *
65
76
  * <code>SidePanel</code> is a layout control that allows primary and additional content to be
66
- * displayed by clicking/tapping the action items from its action bar.
77
+ * displayed by choosing the action items from its action bar.
67
78
  *
68
79
  * <h3>Usage</h3>
69
80
  *
70
81
  * Action bar with action items have two states - collapsed and expanded. In collapsed state
71
82
  * only icons are displayed, and in expanded state both icons and titles are displayed.
72
83
  *
73
- * Each action item can have a content and click/tap on action item toggles the display of its content.
84
+ * Each action item can have a content and choose an action item toggles the display of its content.
74
85
  * The content can be added to the action item's <code>content</code> aggregation, or can be added or
75
86
  * changed later.
76
87
  *
@@ -91,13 +102,7 @@ sap.ui.define([
91
102
  * action items, an overflow icon is displayed, and it toggles ON/OFF an overflow menu with the rest
92
103
  * of the action items that are not visible at the moment.
93
104
  *
94
- * Screen width > 1440 px
95
- *
96
- * <ul><li>When expanded, the side content shrinks the main content.</li></ul>
97
- *
98
- * Screen width <= 1440 px
99
- *
100
- * <ul><li>When expanded, the side content is placed over the main content.</li></ul>
105
+ * When expanded, the side content shrinks the main content.
101
106
  *
102
107
  * <b>On mobile device</b>
103
108
  *
@@ -105,6 +110,14 @@ sap.ui.define([
105
110
  * display, and when expanded, the side content is displayed above the action bar. If there is not enough
106
111
  * room for all action items, the action bar can be swiped to access the rest of the action items.
107
112
  *
113
+ * <h3>Resizing</h3>
114
+ *
115
+ * Resizing functionality only affects desktop or tablet devices.
116
+ *
117
+ * By setting the <code>sidePanelResizable</code> property, the expanded side panel can be resized
118
+ * by mouse (by drag or by double click on resize splitter), by keyboard or by choosing one of three predefined positions
119
+ * in the side panel's context menu (min, max and default widths)
120
+ *
108
121
  * <h3>Keyboard shortcuts</h3>
109
122
  *
110
123
  * <ul>
@@ -117,16 +130,26 @@ sap.ui.define([
117
130
  * <li>[Esc] - Close the opened side content panel and set focus back to main content</li>
118
131
  * </ul>
119
132
  *
133
+ * If the side panel's <code>sidePanelResizable</code> property is set, there is an action item chosen, and the resize splitter is focused:
134
+ *
135
+ * <ul>
136
+ * <li>[Home] - set the expanded side panel width to the minimum value defined in <code>sidePanelMinWidth</code> property</li>
137
+ * <li>[End] - set the expanded side panel width to the maximum value defined in <code>sidePanelMaxWidth</code> property</li>
138
+ * <li>[Enter] - set the expanded side panel width to the default value defined in <code>sidePanelWidth</code> property</li>
139
+ * <li>[Shift]+[F10] or [Context menu] - show the resize context menu</li>
140
+ * <li>[Arrow Left] / [Arrow Right] - increase/decrease the width of the expanded side panel with the regular step</li>
141
+ * <li>[Shift] + [Arrow Left] / [Arrow Right] - increase/decrease the width of the expanded side panel with the larger step</li>
142
+ * </ul>
143
+ *
120
144
  * @extends sap.ui.core.Control
121
145
  *
122
146
  * @author SAP SE
123
- * @version 1.108.1
147
+ * @version 1.109.0
124
148
  *
125
149
  * @constructor
126
150
  * @public
127
151
  * @since 1.107
128
152
  * @alias sap.f.SidePanel
129
- * @experimental Since 1.107. This class is experimental and provides only limited functionality. Also the API might be changed in future.
130
153
  * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
131
154
  */
132
155
  var SidePanel = Control.extend("sap.f.SidePanel", {
@@ -143,6 +166,13 @@ sap.ui.define([
143
166
  */
144
167
  ariaLabel: {type: "string", group: "Accessibility", defaultValue: "Side Panel" },
145
168
 
169
+ /**
170
+ * Determines whether the side panel is resizable or fixed.
171
+ * <b>Note:</b> setting this property only affects desktop or tablet devices.
172
+ * @since: 1.109
173
+ */
174
+ sidePanelResizable: {type: "boolean", group: "Appearance", defaultValue: false},
175
+
146
176
  /**
147
177
  * Determines the side panel width (Side Content width + Action Bar width).
148
178
  * <b>Note:</b> if the width is given in percent(%), it is calculated as given percent from the Side Panel parent container width,
@@ -154,17 +184,33 @@ sap.ui.define([
154
184
  * Determines the minimum side panel width (Side Content width + Action Bar width).
155
185
  * <b>Note:</b> if the width is given in percent(%), it is calculated as given percent from the Side Panel parent container width,
156
186
  * otherwise it's calculated in absolute units.
157
- * @private
187
+ * @since 1.109.0
158
188
  */
159
- sidePanelMinWidth: { type: "sap.ui.core.CSSSize", group: "Appearance", defaultValue: "10%", visibility: "hidden" },
189
+ sidePanelMinWidth: { type: "sap.ui.core.CSSSize", group: "Appearance", defaultValue: "15rem"},
160
190
 
161
191
  /**
162
192
  * Determines the maximum side panel width (Side Content width + Action Bar width).
163
193
  * <b>Note:</b> if the width is given in percent(%), it is calculated as given percent from the Side Panel parent container width,
164
194
  * otherwise it's calculated in absolute units.
165
- * @private
195
+ * @since 1.109.0
196
+ */
197
+ sidePanelMaxWidth: { type: "sap.ui.core.CSSSize", group: "Appearance", defaultValue: "90%"},
198
+
199
+ /**
200
+ * Determines the step (in pixels) when changing the width of the side panel with the keyboard.
201
+ * <b>Note:</b> the width can be changed by this step with <code>Left Arrow</code> and <code>Right Arrow</code>
202
+ * keys when the resize splitter is focused.
203
+ * @since 1.109.0
204
+ */
205
+ sidePanelResizeStep: { type: "int", group: "Appearance", defaultValue: 10},
206
+
207
+ /**
208
+ * Determines the large step (in pixels) when changing the width of the side panel with the keyboard.
209
+ * <b>Note:</b> the width can be changed by large step with <code>Shift + Left Arrow</code> and
210
+ * <code>Shift + Right Arrow</code> keys when the resize splitter is focused.
211
+ * @since 1.109.0
166
212
  */
167
- sidePanelMaxWidth: { type: "sap.ui.core.CSSSize", group: "Appearance", defaultValue: "90%", visibility: "hidden" },
213
+ sidePanelResizeLargerStep: { type: "int", group: "Appearance", defaultValue: 100},
168
214
 
169
215
  /**
170
216
  * Determines whether the side content is visible or hidden.
@@ -203,7 +249,13 @@ sap.ui.define([
203
249
  /**
204
250
  * Overflow menu. It displays action items that don't fit in the available height of the side panel.
205
251
  */
206
- _overflowMenu: { type: "sap.m.Menu", multiple: false, visibility: "hidden"}
252
+ _overflowMenu: { type: "sap.m.Menu", multiple: false, visibility: "hidden"},
253
+
254
+ /**
255
+ * Context menu. It displays predefined options for side panel resize.
256
+ */
257
+ _contextMenu: { type: "sap.m.Menu", multiple: false, visibility: "hidden"}
258
+
207
259
  },
208
260
  associations: {
209
261
  /**
@@ -270,11 +322,19 @@ sap.ui.define([
270
322
  this.setAggregation("_overflowMenu", oMenu);
271
323
  }
272
324
 
273
- this._onResizeRef = this._onResize.bind(this);
274
- this._onMainScroll = this._handleScroll.bind(this);
325
+ this._fnOnResizeRef = this._onResize.bind(this);
326
+ this._fnOnMainScroll = this._handleScroll.bind(this);
327
+ this._fnOnMainFocusOut = this._onMainFocusOut.bind(this);
328
+ this._fnOnTouchStart = this._onTouchStart.bind(this);
329
+ this._fnOnTouchEnd = this._onTouchEnd.bind(this);
330
+ this._fnOnTouchMove = this._onTouchMove.bind(this);
331
+ this._fnOnDblClick = this._onDblClick.bind(this);
275
332
 
276
333
  this._iLastScrollPosition = 0;
277
334
 
335
+ this._iSidePanelPosition = SIDE_PANEL_POSITION_INITIAL; // possible values: SIDE_PANEL_POSITION_MIN_WIDTH/SIDE_PANEL_POSITION_INITIAL/SIDE_PANEL_POSITION_MAX_WIDTH
336
+ this._bShouldAttachGlobalHandlers = true; // flag for attachment of "global" event handlers (on whole Side Panel control)
337
+
278
338
  this._iVisibleItems = 0; // how many action items can fit in the available height of the action bar
279
339
  this._bOverflowMenuOpened = false; // whether the overflow menu is opened or not
280
340
  this._mOverflowItemsMap = {}; // map of the items placed in overflow menu in format {menu item Id: SidePanelItem}
@@ -286,6 +346,24 @@ sap.ui.define([
286
346
  this._detachResizeHandlers();
287
347
  this._detachScrollHandler();
288
348
  this._detachMainFocusOutHandler();
349
+ this._detachResizableHandlers();
350
+ };
351
+
352
+ /**
353
+ * Override <code>sidePanelWidth</code> property setter.
354
+ *
355
+ * Sets the width of the side panel.
356
+ *
357
+ * @param {sap.ui.core.CSSSize} oWidth width of the side panel.
358
+ * @returns {this} this for method chaining
359
+ */
360
+ SidePanel.prototype.setSidePanelWidth = function(oWidth) {
361
+ this.setProperty("sidePanelWidth", oWidth);
362
+ if (this.getDomRef()) {
363
+ this._sSidePanelWidth = this._getSidePanelWidth();
364
+ }
365
+
366
+ return this;
289
367
  };
290
368
 
291
369
  /**
@@ -334,9 +412,9 @@ sap.ui.define([
334
412
 
335
413
  this._detachResizeHandlers();
336
414
  this._attachResizeHandlers();
337
-
338
415
  this._detachScrollHandler();
339
416
  this._detachMainFocusOutHandler();
417
+ this._detachResizableHandlers();
340
418
 
341
419
  this._oInvisibleMessage = InvisibleMessage.getInstance();
342
420
  };
@@ -345,22 +423,22 @@ sap.ui.define([
345
423
  var oArrowButton = this._isSingleItem() && this.getActionBarExpanded()
346
424
  ? this.getAggregation("_closeButton")
347
425
  : this.getAggregation("_arrowButton"),
348
- oDomRef;
426
+ oArrowDomRef;
349
427
 
350
428
  if (!Device.system.phone) {
351
- oDomRef = oArrowButton.getDomRef();
352
- oDomRef && oDomRef.setAttribute("aria-expanded", this.getActionBarExpanded() ? "true" : "false");
429
+ oArrowDomRef = oArrowButton.getDomRef();
430
+ oArrowDomRef && oArrowDomRef.setAttribute("aria-expanded", this.getActionBarExpanded() ? "true" : "false");
353
431
  }
354
432
 
355
433
  !this._getSideContentExpanded() && this._attachScrollHandler();
356
-
357
434
  this._attachMainFocusOutHandler();
435
+ this._attachResizableHandlers();
358
436
 
359
437
  if (!Device.system.phone) {
360
438
  if (!this._isSingleItem() && this._iVisibleItems > 0) {
361
439
  this._initItemNavigation();
362
440
  }
363
- if (this.getActionBarExpanded() || this._getSideContentExpanded()) {
441
+ if (this._getSideContentExpanded()) {
364
442
  this.getItems().length && this._fixSidePanelWidth();
365
443
  }
366
444
  } else {
@@ -369,14 +447,32 @@ sap.ui.define([
369
447
  }
370
448
  }
371
449
 
450
+ if (!this._sSidePanelWidth) {
451
+ this._sSidePanelWidth = this._getSidePanelWidth();
452
+ }
453
+ };
454
+
455
+ SidePanel.prototype.oncontextmenu = function(oEvent) {
456
+ var bSplitterFocused = document.activeElement === this.getDomRef().querySelector(".sapFSPSplitterBar");
457
+
458
+ if (bSplitterFocused || oEvent.target.closest(".sapFSPSide.sapFSPResizable")) {
459
+ // show the resize context menu only if there is a keyboard call ([Shift]+[F10] or [Context menu] keys)
460
+ // from focused splitter bar or right click somewhere within the side panel
461
+ oEvent.preventDefault();
462
+ if (bSplitterFocused){
463
+ this._bContextMenuFromSplitter = true;
464
+ }
465
+ this._showResizeContextMenu(oEvent);
466
+ }
372
467
  };
373
468
 
374
469
  SidePanel.prototype.onkeydown = function(oEvent) {
375
470
  var oTarget = oEvent.target,
376
- oActionBarDom = this.$().find(".sapFSPActionBar")[0],
471
+ oActionBarDom = this.getDomRef().querySelector(".sapFSPActionBarList"),
377
472
  bSideContentExpanded = this._getSideContentExpanded(),
378
473
  bSideExpanded = this.getActionBarExpanded() || bSideContentExpanded,
379
- bCtrlOrCmd = oEvent.ctrlKey || oEvent.metaKey;
474
+ bCtrlOrCmd = oEvent.ctrlKey || oEvent.metaKey,
475
+ bSplitterFocused = document.activeElement === this.getDomRef().querySelector(".sapFSPSplitterBar");
380
476
 
381
477
  if (bCtrlOrCmd && oEvent.which === KeyCodes.ARROW_LEFT) {
382
478
  oEvent.preventDefault();
@@ -404,6 +500,32 @@ sap.ui.define([
404
500
  this.setActionBarExpanded(false);
405
501
  this._closeSideContent();
406
502
  this._focusMain();
503
+ } else if (bSplitterFocused) {
504
+ // resize splitter keyboard handling
505
+ switch (oEvent.which) {
506
+ case KeyCodes.ENTER:
507
+ this._setSidePanelResizePosition(SIDE_PANEL_POSITION_INITIAL);
508
+ break;
509
+ case KeyCodes.END:
510
+ this._setSidePanelResizePosition(SIDE_PANEL_POSITION_MAX_WIDTH);
511
+ break;
512
+ case KeyCodes.HOME:
513
+ this._setSidePanelResizePosition(SIDE_PANEL_POSITION_MIN_WIDTH);
514
+ break;
515
+ case KeyCodes.ARROW_LEFT:
516
+ this._moveSidePanelResizePositionWith(oEvent.shiftKey ? this.getSidePanelResizeLargerStep() : this.getSidePanelResizeStep());
517
+ break;
518
+ case KeyCodes.ARROW_RIGHT:
519
+ this._moveSidePanelResizePositionWith(oEvent.shiftKey ? -this.getSidePanelResizeLargerStep() : -this.getSidePanelResizeStep());
520
+ break;
521
+ case KeyCodes.F10:
522
+ if (oEvent.shiftKey) {
523
+ oEvent.preventDefault();
524
+ this._bContextMenuFromSplitter = true;
525
+ this._showResizeContextMenu(oEvent);
526
+ }
527
+ break;
528
+ }
407
529
  }
408
530
 
409
531
  if (!containsOrEquals(oActionBarDom, oTarget) || oTarget === oActionBarDom) {
@@ -424,7 +546,7 @@ sap.ui.define([
424
546
 
425
547
  SidePanel.prototype.onkeyup = function(oEvent) {
426
548
  var oTarget = oEvent.target,
427
- oActionBarDom = this.$().find(".sapFSPActionBar")[0];
549
+ oActionBarDom = this.getDomRef().querySelector(".sapFSPActionBarList");
428
550
 
429
551
  if (!containsOrEquals(oActionBarDom, oTarget) || oTarget === oActionBarDom) {
430
552
  return;
@@ -438,7 +560,7 @@ sap.ui.define([
438
560
  SidePanel.prototype.ontap = function(oEvent) {
439
561
  var oItemDom,
440
562
  oTarget = oEvent.target,
441
- oActionBarDom = this.$().find(".sapFSPActionBar")[0];
563
+ oActionBarDom = this.getDomRef().querySelector(".sapFSPActionBarList");
442
564
 
443
565
  if (!containsOrEquals(oActionBarDom, oTarget) || oTarget === oActionBarDom) {
444
566
  return;
@@ -478,6 +600,44 @@ sap.ui.define([
478
600
 
479
601
  // Private methods
480
602
 
603
+ SidePanel.prototype._getContextMenu = function() {
604
+ var oContextMenu = this.getAggregation("_contextMenu");
605
+
606
+ if (!oContextMenu) {
607
+ oContextMenu = new Menu({
608
+ items: [
609
+ new MenuItem({
610
+ text: oResourceBundle.getText("SIDEPANEL_CONTEXTMENU_MAXIMUM_WIDTH"),
611
+ press: function() {
612
+ this._setSidePanelResizePosition(SIDE_PANEL_POSITION_MAX_WIDTH);
613
+ }.bind(this)
614
+ }),
615
+ new MenuItem({
616
+ text: oResourceBundle.getText("SIDEPANEL_CONTEXTMENU_MINIMUM_WIDTH"),
617
+ press: function() {
618
+ this._setSidePanelResizePosition(SIDE_PANEL_POSITION_MIN_WIDTH);
619
+ }.bind(this)
620
+ }),
621
+ new MenuItem({
622
+ text: oResourceBundle.getText("SIDEPANEL_CONTEXTMENU_DEFAULT_WIDTH"),
623
+ press: function() {
624
+ this._setSidePanelResizePosition(SIDE_PANEL_POSITION_INITIAL);
625
+ }.bind(this)
626
+ })
627
+ ],
628
+ closed: function(oEvent) {
629
+ if (this._bContextMenuFromSplitter) {
630
+ this._bContextMenuFromSplitter = false;
631
+ this.getDomRef().querySelector(".sapFSPSplitterBar").focus();
632
+ }
633
+ }.bind(this)
634
+ });
635
+ this.setAggregation("_contextMenu", oContextMenu);
636
+ }
637
+
638
+ return oContextMenu;
639
+ };
640
+
481
641
  SidePanel.prototype._getSideContentExpanded = function() {
482
642
  return this.getProperty("sideContentExpanded");
483
643
  };
@@ -643,7 +803,7 @@ sap.ui.define([
643
803
  };
644
804
 
645
805
  SidePanel.prototype._attachResizeHandlers = function () {
646
- this._iResizeHandlerId = ResizeHandler.register(this, this._onResizeRef);
806
+ this._iResizeHandlerId = ResizeHandler.register(this, this._fnOnResizeRef);
647
807
  };
648
808
 
649
809
  SidePanel.prototype._detachResizeHandlers = function () {
@@ -660,55 +820,66 @@ sap.ui.define([
660
820
 
661
821
  var iCurrentWidth = oEvent.size.width,
662
822
  bSingleItem = this._isSingleItem(),
663
- oStyle = window.getComputedStyle(this.$().find(".sapFSPActionBar")[0]),
823
+ oDomRef = this.getDomRef(),
824
+ oStyle = window.getComputedStyle(oDomRef.querySelector(".sapFSPActionBarList")),
664
825
  iItemsGap = parseInt(oStyle.gap),
665
826
  iMarginBottom = parseInt(oStyle.marginBottom),
666
827
  iMarginTop = parseInt(oStyle.marginTop),
667
- oFirstItem = this.$().find(".sapFSPOverflowItem")[0],
828
+ oFirstItem = oDomRef.querySelector(".sapFSPOverflowItem"),
668
829
  iItemsHeight = oFirstItem && oFirstItem.clientHeight,
669
- iActionBarHeight,
670
- iCurrentWidth;
671
-
672
- if (iCurrentWidth < 1440 && (this._iPreviousWidth === undefined || this._iPreviousWidth >= 1440)) {
673
- this.addStyleClass("sapFSPSizeMedium");
674
- } else if (iCurrentWidth >= 1440 && (this._iPreviousWidth === undefined || this._iPreviousWidth < 1440)) {
675
- this.removeStyleClass("sapFSPSizeMedium");
676
- }
830
+ iActionBarHeight;
677
831
 
678
832
  this._iPreviousWidth = iCurrentWidth;
679
833
 
680
- if (!Device.system.phone) {
681
- if (!bSingleItem) {
682
- iActionBarHeight = this.$().find(".sapFSPSideInner")[0].clientHeight - iMarginBottom - iMarginTop;
683
- this._iVisibleItems = parseInt((iActionBarHeight + iItemsGap) / (iItemsHeight + iItemsGap));
684
- this._initItemNavigation();
685
- }
686
- if (this.getActionBarExpanded() || this._getSideContentExpanded()) {
687
- this._fixSidePanelWidth();
688
- }
834
+ if (Device.system.phone) {
835
+ return;
836
+ }
837
+
838
+ if (!bSingleItem) {
839
+ iActionBarHeight = oDomRef.querySelector(".sapFSPSideInner").clientHeight - iMarginBottom - iMarginTop;
840
+ this._iVisibleItems = parseInt((iActionBarHeight + iItemsGap) / (iItemsHeight + iItemsGap));
841
+ this._initItemNavigation();
842
+ }
843
+ if (this._getSideContentExpanded()) {
844
+ this._fixSidePanelWidth();
689
845
  }
690
846
  };
691
847
 
692
848
  SidePanel.prototype._fixSidePanelWidth = function() {
693
- var oSide = this.getDomRef().querySelector(".sapFSPSide"),
694
- oSideInner = this.getDomRef().querySelector(".sapFSPSideInner"),
849
+ var oDomRef = this.getDomRef(),
850
+ oSide = oDomRef.querySelector(".sapFSPSide"),
695
851
  iControlWidth = this._getControlWidth(),
696
- iSidePanelWidth = parseInt(window.getComputedStyle(oSideInner).width),
697
- bResizeSidePanel = iControlWidth < iSidePanelWidth; // doesn't work stable
852
+ iSidePanelWidth = parseInt(window.getComputedStyle(oSide).width),
853
+ bResizeSidePanel = iControlWidth < iSidePanelWidth;
854
+
855
+ oSide.style.width = bResizeSidePanel ? iControlWidth + "px" : this._getSidePanelWidth();
856
+ oSide.style.minWidth = bResizeSidePanel ? iControlWidth + "px" : this._getSidePanelMinWidth();
857
+ oSide.style.maxWidth = this._getSidePanelMaxWidth();
858
+
859
+ this._updateSplitViewClass(oSide);
860
+ this.getSidePanelResizable() && this._updateAriaValues();
861
+ };
698
862
 
699
- if (!this.hasStyleClass("sapFSPSizeMedium")) {
700
- oSide.style.width = bResizeSidePanel ? iControlWidth + "px" : this._getSidePanelWidth();
701
- oSide.style.minWidth = bResizeSidePanel ? iControlWidth + "px" : this._getSidePanelMinWidth();
702
- oSide.style.maxWidth = this._getSidePanelMaxWidth();
863
+ SidePanel.prototype._updateSplitViewClass = function(oSide) {
864
+ var iSidePanelWidth = parseInt(window.getComputedStyle(oSide).width);
865
+
866
+ if (iSidePanelWidth > SIDE_PANEL_SPLIT_BREAKPOINT) {
867
+ oSide.classList.add("sapFSPSplitView");
703
868
  } else {
704
- oSide.style.width = "";
705
- oSide.style.minWidth = "";
706
- oSide.style.maxWidth = "";
869
+ oSide.classList.contains("sapFSPSplitView") && this.setActionBarExpanded(false);
870
+ oSide.classList.remove("sapFSPSplitView");
707
871
  }
872
+ };
873
+
874
+ SidePanel.prototype._updateAriaValues = function() {
875
+ var oDomRef = this.getDomRef(),
876
+ oSplitter = oDomRef.querySelector(".sapFSPSplitterBar"),
877
+ iControlWidth = this._getControlWidth(),
878
+ iSidePanelWidth = parseInt(window.getComputedStyle(oDomRef.querySelector(".sapFSPSide")).width);
708
879
 
709
- oSideInner.style.width = bResizeSidePanel ? iControlWidth + "px" : this._getSidePanelWidth();
710
- oSideInner.style.minWidth = bResizeSidePanel ? iControlWidth + "px" : this._getSidePanelMinWidth();
711
- oSideInner.style.maxWidth = this._getSidePanelMaxWidth();
880
+ oSplitter.setAttribute("aria-valuenow", Math.round(iSidePanelWidth / iControlWidth * 100));
881
+ oSplitter.setAttribute("aria-valuemin", Math.round(parseInt(window.getComputedStyle(oDomRef.querySelector(".sapFSPMinWidth")).width) / iControlWidth * 100));
882
+ oSplitter.setAttribute("aria-valuemax", Math.round(parseInt(window.getComputedStyle(oDomRef.querySelector(".sapFSPMaxWidth")).width) / iControlWidth * 100));
712
883
  };
713
884
 
714
885
  SidePanel.prototype._setOverflowItemSelection = function(bState) {
@@ -742,6 +913,10 @@ sap.ui.define([
742
913
  return oResourceBundle.getText("SIDEPANEL_CONTENT_ARIA_LABEL");
743
914
  };
744
915
 
916
+ SidePanel.prototype._getSplitterTitle = function () {
917
+ return oResourceBundle.getText("SIDEPANEL_RESIZE_SPLITTER_TITLE");
918
+ };
919
+
745
920
  SidePanel.prototype._toggleItemSelection = function(oItem) {
746
921
  var oNewSelectedItem,
747
922
  oSelectedItem = this.getSelectedItem(),
@@ -836,10 +1011,6 @@ sap.ui.define([
836
1011
  }
837
1012
  };
838
1013
 
839
- SidePanel.prototype._isSideContentExpanded = function() {
840
- return (Device.system.phone || (!this.getActionBarExpanded() || this._isSingleItem())) && this._getSideContentExpanded();
841
- };
842
-
843
1014
  SidePanel.prototype._getSelectedItem = function() {
844
1015
  return Core.byId(this.getSelectedItem());
845
1016
  };
@@ -890,11 +1061,13 @@ sap.ui.define([
890
1061
  oOverflowItem = this.getAggregation("_overflowItem");
891
1062
 
892
1063
  this._bAnnounceSelected = false;
893
- // set proper focus
894
- if (this.$().find("#" + oSelectedItem.getId()).css("display") === "none") {
895
- oOverflowItem && oOverflowItem.focus();
896
- } else {
897
- oSelectedItem && oSelectedItem.focus();
1064
+ if (!this._isSingleItem()) {
1065
+ // set proper focus
1066
+ if (this.getDomRef().querySelector("#" + oSelectedItem.getId()).style.display === "none") {
1067
+ oOverflowItem && oOverflowItem.focus();
1068
+ } else {
1069
+ oSelectedItem && oSelectedItem.focus();
1070
+ }
898
1071
  }
899
1072
  this._closeSideContent();
900
1073
  }.bind(this)
@@ -911,7 +1084,7 @@ sap.ui.define([
911
1084
  return;
912
1085
  }
913
1086
 
914
- this.$().find(".sapFSPMain")[0].addEventListener('scroll', this._onMainScroll);
1087
+ this.getDomRef().querySelector(".sapFSPMain").addEventListener('scroll', this._fnOnMainScroll);
915
1088
  };
916
1089
 
917
1090
  SidePanel.prototype._detachScrollHandler = function() {
@@ -919,7 +1092,7 @@ sap.ui.define([
919
1092
  return;
920
1093
  }
921
1094
 
922
- this.$().find(".sapFSPMain")[0].removeEventListener('scroll', this._onMainScroll);
1095
+ this.getDomRef().querySelector(".sapFSPMain").removeEventListener('scroll', this._fnOnMainScroll);
923
1096
  };
924
1097
 
925
1098
  SidePanel.prototype._closeOverflowMenu = function() {
@@ -932,14 +1105,14 @@ sap.ui.define([
932
1105
  SidePanel.prototype._attachMainFocusOutHandler = function() {
933
1106
  if (!Device.system.phone) {
934
1107
  var oDomRef = this.getDomRef();
935
- oDomRef && oDomRef.querySelector(".sapFSPMain").addEventListener("focusout", this._onMainFocusOut.bind(this), false);
1108
+ oDomRef && oDomRef.querySelector(".sapFSPMain").addEventListener("focusout", this._fnOnMainFocusOut, false);
936
1109
  }
937
1110
  };
938
1111
 
939
1112
  SidePanel.prototype._detachMainFocusOutHandler = function() {
940
1113
  if (!Device.system.phone) {
941
1114
  var oDomRef = this.getDomRef();
942
- oDomRef && oDomRef.querySelector(".sapFSPMain").removeEventListener("focusout", this._onMainFocusOut.bind(this), false);
1115
+ oDomRef && oDomRef.querySelector(".sapFSPMain").removeEventListener("focusout", this._fnOnMainFocusOut, false);
943
1116
  }
944
1117
  };
945
1118
 
@@ -976,7 +1149,7 @@ sap.ui.define([
976
1149
  * @private
977
1150
  */
978
1151
  SidePanel.prototype._handleGroupNavigation = function(oEvent, bShiftKey) {
979
- var oEventF6 = jQuery.Event("keydown");
1152
+ var oEventF6 = new jQuery.Event("keydown");
980
1153
 
981
1154
  this.$().trigger("focus");
982
1155
 
@@ -991,17 +1164,21 @@ sap.ui.define([
991
1164
  return this.getItems().length === 1;
992
1165
  };
993
1166
 
994
- SidePanel.prototype._calculatePixelWidth = function(sWidth) {
995
- sWidth = sWidth.replace(/\s/g, '');
996
- if (sWidth.slice(-1) === "%") {
997
- sWidth = parseInt(this._getControlWidth() * parseFloat(sWidth) / 100) + "px";
1167
+ SidePanel.prototype._calculatePixelWidth = function(vWidth) {
1168
+ if (typeof vWidth === "string") {
1169
+ vWidth = vWidth.replace(/\s/g, '');
1170
+ if (vWidth.slice(-1) === "%") {
1171
+ vWidth = parseInt(this._getControlWidth() * parseFloat(vWidth) / 100) + "px";
1172
+ }
1173
+ } else {
1174
+ vWidth = vWidth.toString() + "px";
998
1175
  }
999
1176
 
1000
- return sWidth;
1177
+ return vWidth;
1001
1178
  };
1002
1179
 
1003
1180
  SidePanel.prototype._getControlWidth = function() {
1004
- return parseInt(this.$().css("width"));
1181
+ return parseInt(window.getComputedStyle(this.getDomRef()).width);
1005
1182
  };
1006
1183
 
1007
1184
  SidePanel.prototype._getSidePanelWidth = function() {
@@ -1009,11 +1186,141 @@ sap.ui.define([
1009
1186
  };
1010
1187
 
1011
1188
  SidePanel.prototype._getSidePanelMinWidth = function() {
1012
- return this._calculatePixelWidth(this.getProperty("sidePanelMinWidth"));
1189
+ return this._calculatePixelWidth(this.getSidePanelMinWidth());
1013
1190
  };
1014
1191
 
1015
1192
  SidePanel.prototype._getSidePanelMaxWidth = function() {
1016
- return this._calculatePixelWidth(this.getProperty("sidePanelMaxWidth"));
1193
+ return this._calculatePixelWidth(this.getSidePanelMaxWidth());
1194
+ };
1195
+
1196
+ // Side Panel resizable-related methods
1197
+
1198
+ SidePanel.prototype._isResizable = function() {
1199
+ return this.getSidePanelResizable() && !Device.system.phone && (this.getActionBarExpanded() || this._getSideContentExpanded());
1200
+ };
1201
+
1202
+ SidePanel.prototype._attachResizableHandlers = function() {
1203
+ var oDomRef = this.getDomRef(),
1204
+ oSplitter = oDomRef && oDomRef.querySelector(".sapFSPSplitterBar");
1205
+
1206
+ if (!oSplitter) {
1207
+ return;
1208
+ }
1209
+
1210
+ if (Device.system.combi || Device.system.phone || Device.system.tablet) {
1211
+ // Attach touch events
1212
+ oSplitter.addEventListener("touchstart", this._fnOnTouchStart);
1213
+ oSplitter.addEventListener("touchend", this._fnOnTouchEnd);
1214
+ oSplitter.addEventListener("touchmove", this._fnOnTouchMove);
1215
+ }
1216
+ if (Device.system.desktop || Device.system.combi) {
1217
+ // Attach mouse events
1218
+ oSplitter.addEventListener("dblclick", this._fnOnDblClick);
1219
+ oSplitter.addEventListener("mousedown", this._fnOnTouchStart);
1220
+ oDomRef.addEventListener("mouseup", this._fnOnTouchEnd);
1221
+ oDomRef.addEventListener("mousemove", this._fnOnTouchMove);
1222
+ }
1223
+ };
1224
+
1225
+ SidePanel.prototype._detachResizableHandlers = function() {
1226
+ var oDomRef = this.getDomRef(),
1227
+ oSplitter = oDomRef && oDomRef.querySelector(".sapFSPSplitterBar");
1228
+
1229
+ if (!oSplitter) {
1230
+ return;
1231
+ }
1232
+
1233
+ if (Device.system.combi || Device.system.phone || Device.system.tablet) {
1234
+ // Detach touch events
1235
+ oSplitter.removeEventListener("touchstart", this._fnOnTouchStart);
1236
+ oSplitter.removeEventListener("touchend", this._fnOnTouchEnd);
1237
+ oSplitter.removeEventListener("touchmove", this._fnOnTouchMove);
1238
+ }
1239
+ if (Device.system.desktop || Device.system.combi) {
1240
+ // Detach mouse events
1241
+ oSplitter.removeEventListener("dblclick", this._fnOnDblClick);
1242
+ oSplitter.removeEventListener("mousedown", this._fnOnTouchStart);
1243
+ oDomRef.removeEventListener("mouseup", this._fnOnTouchEnd);
1244
+ oDomRef.removeEventListener("mousemove", this._fnOnTouchMove);
1245
+ }
1246
+
1247
+ };
1248
+
1249
+ SidePanel.prototype._onTouchStart = function(oEvent) {
1250
+ oEvent.preventDefault();
1251
+ this.getDomRef().querySelector(".sapFSPSplitterBar").classList.add("sapFSPSplitterActive");
1252
+ this._bResizeStarted = true;
1253
+ this._iStartPositionX = oEvent.touches ? oEvent.touches[0].pageX : oEvent.pageX;
1254
+ };
1255
+
1256
+ SidePanel.prototype._onTouchEnd = function(oEvent) {
1257
+ var oDomRef = this.getDomRef(),
1258
+ oSplitter = oDomRef && oDomRef.querySelector(".sapFSPSplitterBar");
1259
+
1260
+ this._bResizeStarted && oEvent.preventDefault();
1261
+ this._bResizeStarted = false;
1262
+
1263
+ oSplitter && oSplitter.classList.remove("sapFSPSplitterActive");
1264
+ };
1265
+
1266
+ SidePanel.prototype._onTouchMove = function(oEvent) {
1267
+ if (!this._bResizeStarted) {
1268
+ return;
1269
+ }
1270
+
1271
+ var iCurrentPositionX = oEvent.touches ? oEvent.touches[0].pageX : oEvent.pageX,
1272
+ iDeltaX = this._iStartPositionX - iCurrentPositionX,
1273
+ oSide = this.getDomRef().querySelector(".sapFSPSide"),
1274
+ iSidePanelWidth = parseInt(window.getComputedStyle(oSide)['width']);
1275
+
1276
+ oEvent.preventDefault();
1277
+
1278
+ if (iSidePanelWidth) {
1279
+ iSidePanelWidth += iDeltaX;
1280
+ this.setProperty("sidePanelWidth", iSidePanelWidth + "px", true);
1281
+ oSide.style.width = iSidePanelWidth + "px";
1282
+ this._iStartPositionX = iCurrentPositionX;
1283
+ this._updateSplitViewClass(oSide);
1284
+ this._updateAriaValues();
1285
+ }
1286
+ };
1287
+
1288
+ SidePanel.prototype._onDblClick = function(oEvent) {
1289
+ oEvent.preventDefault();
1290
+ this._iSidePanelPosition++;
1291
+ if (this._iSidePanelPosition > SIDE_PANEL_POSITION_MAX_WIDTH) {
1292
+ this._iSidePanelPosition = SIDE_PANEL_POSITION_MIN_WIDTH;
1293
+ }
1294
+ this._setSidePanelResizePosition(this._iSidePanelPosition);
1295
+ };
1296
+
1297
+ SidePanel.prototype._setSidePanelResizePosition = function(iResizePosition) {
1298
+ var aPositions = [
1299
+ this._getSidePanelMinWidth(),
1300
+ this._sSidePanelWidth,
1301
+ this._getSidePanelMaxWidth()
1302
+ ];
1303
+
1304
+ this.setProperty("sidePanelWidth", aPositions[iResizePosition], true);
1305
+ this._fixSidePanelWidth();
1306
+ };
1307
+
1308
+ SidePanel.prototype._moveSidePanelResizePositionWith = function(iStep) {
1309
+ var oSide = this.getDomRef().querySelector(".sapFSPSide"),
1310
+ iSidePanelWidth = parseInt(window.getComputedStyle(oSide)['width']);
1311
+
1312
+ if (iStep && iSidePanelWidth) {
1313
+ iSidePanelWidth += iStep;
1314
+ this.setProperty("sidePanelWidth", iSidePanelWidth + "px", true);
1315
+ oSide.style.width = iSidePanelWidth + "px";
1316
+ this._updateAriaValues();
1317
+ }
1318
+ };
1319
+
1320
+ SidePanel.prototype._showResizeContextMenu = function(oEvent) {
1321
+ var oContextMenu = this._getContextMenu();
1322
+
1323
+ (this._bContextMenuFromSplitter && oContextMenu.openBy(this.getDomRef().querySelector(".sapFSPSplitterBarGrip"))) || oContextMenu.openAsContextMenu(oEvent, this);
1017
1324
  };
1018
1325
 
1019
1326
  return SidePanel;