@ui5/webcomponents-fiori 2.19.2 → 2.20.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/CHANGELOG.md +12 -3
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/DynamicPage.js +8 -2
  4. package/dist/DynamicPage.js.map +1 -1
  5. package/dist/ShellBar.d.ts +231 -304
  6. package/dist/ShellBar.js +506 -980
  7. package/dist/ShellBar.js.map +1 -1
  8. package/dist/ShellBarItem.d.ts +15 -31
  9. package/dist/ShellBarItem.js +36 -25
  10. package/dist/ShellBarItem.js.map +1 -1
  11. package/dist/ShellBarItemTemplate.d.ts +2 -0
  12. package/dist/ShellBarItemTemplate.js +11 -0
  13. package/dist/ShellBarItemTemplate.js.map +1 -0
  14. package/dist/ShellBarTemplate.js +53 -55
  15. package/dist/ShellBarTemplate.js.map +1 -1
  16. package/dist/UserMenu.d.ts +10 -1
  17. package/dist/UserMenu.js +9 -1
  18. package/dist/UserMenu.js.map +1 -1
  19. package/dist/UserMenuAccount.js +0 -2
  20. package/dist/UserMenuAccount.js.map +1 -1
  21. package/dist/UserMenuItem.d.ts +0 -1
  22. package/dist/UserMenuItem.js +0 -1
  23. package/dist/UserMenuItem.js.map +1 -1
  24. package/dist/UserMenuItemGroup.d.ts +0 -1
  25. package/dist/UserMenuItemGroup.js +0 -1
  26. package/dist/UserMenuItemGroup.js.map +1 -1
  27. package/dist/UserMenuTemplate.js +3 -1
  28. package/dist/UserMenuTemplate.js.map +1 -1
  29. package/dist/UserSettingsAccountView.js +0 -2
  30. package/dist/UserSettingsAccountView.js.map +1 -1
  31. package/dist/UserSettingsAppearanceView.js +0 -2
  32. package/dist/UserSettingsAppearanceView.js.map +1 -1
  33. package/dist/UserSettingsAppearanceViewGroup.d.ts +0 -1
  34. package/dist/UserSettingsAppearanceViewGroup.js +0 -1
  35. package/dist/UserSettingsAppearanceViewGroup.js.map +1 -1
  36. package/dist/UserSettingsAppearanceViewItem.js +0 -2
  37. package/dist/UserSettingsAppearanceViewItem.js.map +1 -1
  38. package/dist/UserSettingsDialog.d.ts +0 -1
  39. package/dist/UserSettingsDialog.js +0 -1
  40. package/dist/UserSettingsDialog.js.map +1 -1
  41. package/dist/UserSettingsItem.d.ts +0 -1
  42. package/dist/UserSettingsItem.js +0 -1
  43. package/dist/UserSettingsItem.js.map +1 -1
  44. package/dist/UserSettingsView.d.ts +0 -1
  45. package/dist/UserSettingsView.js +0 -1
  46. package/dist/UserSettingsView.js.map +1 -1
  47. package/dist/css/themes/ShellBar.css +1 -1
  48. package/dist/css/themes/ShellBarItem.css +1 -0
  49. package/dist/css/themes/ShellBarLegacy.css +1 -0
  50. package/dist/css/themes/ShellBarSearchLegacy.css +1 -0
  51. package/dist/custom-elements-internal.json +363 -750
  52. package/dist/custom-elements.json +324 -609
  53. package/dist/generated/assets/i18n/messagebundle_ar.json +1 -1
  54. package/dist/generated/assets/i18n/messagebundle_bg.json +1 -1
  55. package/dist/generated/assets/i18n/messagebundle_ca.json +1 -1
  56. package/dist/generated/assets/i18n/messagebundle_cnr.json +1 -1
  57. package/dist/generated/assets/i18n/messagebundle_cs.json +1 -1
  58. package/dist/generated/assets/i18n/messagebundle_cy.json +1 -1
  59. package/dist/generated/assets/i18n/messagebundle_da.json +1 -1
  60. package/dist/generated/assets/i18n/messagebundle_de.json +1 -1
  61. package/dist/generated/assets/i18n/messagebundle_el.json +1 -1
  62. package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
  63. package/dist/generated/assets/i18n/messagebundle_en_GB.json +1 -1
  64. package/dist/generated/assets/i18n/messagebundle_en_US_sappsd.json +1 -1
  65. package/dist/generated/assets/i18n/messagebundle_en_US_saprigi.json +1 -1
  66. package/dist/generated/assets/i18n/messagebundle_en_US_saptrc.json +1 -1
  67. package/dist/generated/assets/i18n/messagebundle_es.json +1 -1
  68. package/dist/generated/assets/i18n/messagebundle_es_MX.json +1 -1
  69. package/dist/generated/assets/i18n/messagebundle_et.json +1 -1
  70. package/dist/generated/assets/i18n/messagebundle_fi.json +1 -1
  71. package/dist/generated/assets/i18n/messagebundle_fr.json +1 -1
  72. package/dist/generated/assets/i18n/messagebundle_fr_CA.json +1 -1
  73. package/dist/generated/assets/i18n/messagebundle_hi.json +1 -1
  74. package/dist/generated/assets/i18n/messagebundle_hr.json +1 -1
  75. package/dist/generated/assets/i18n/messagebundle_hu.json +1 -1
  76. package/dist/generated/assets/i18n/messagebundle_id.json +1 -1
  77. package/dist/generated/assets/i18n/messagebundle_it.json +1 -1
  78. package/dist/generated/assets/i18n/messagebundle_iw.json +1 -1
  79. package/dist/generated/assets/i18n/messagebundle_ja.json +1 -1
  80. package/dist/generated/assets/i18n/messagebundle_kk.json +1 -1
  81. package/dist/generated/assets/i18n/messagebundle_ko.json +1 -1
  82. package/dist/generated/assets/i18n/messagebundle_lt.json +1 -1
  83. package/dist/generated/assets/i18n/messagebundle_lv.json +1 -1
  84. package/dist/generated/assets/i18n/messagebundle_mk.json +1 -1
  85. package/dist/generated/assets/i18n/messagebundle_ms.json +1 -1
  86. package/dist/generated/assets/i18n/messagebundle_nl.json +1 -1
  87. package/dist/generated/assets/i18n/messagebundle_no.json +1 -1
  88. package/dist/generated/assets/i18n/messagebundle_pl.json +1 -1
  89. package/dist/generated/assets/i18n/messagebundle_pt.json +1 -1
  90. package/dist/generated/assets/i18n/messagebundle_pt_PT.json +1 -1
  91. package/dist/generated/assets/i18n/messagebundle_ro.json +1 -1
  92. package/dist/generated/assets/i18n/messagebundle_ru.json +1 -1
  93. package/dist/generated/assets/i18n/messagebundle_sh.json +1 -1
  94. package/dist/generated/assets/i18n/messagebundle_sk.json +1 -1
  95. package/dist/generated/assets/i18n/messagebundle_sl.json +1 -1
  96. package/dist/generated/assets/i18n/messagebundle_sr.json +1 -1
  97. package/dist/generated/assets/i18n/messagebundle_sv.json +1 -1
  98. package/dist/generated/assets/i18n/messagebundle_th.json +1 -1
  99. package/dist/generated/assets/i18n/messagebundle_tr.json +1 -1
  100. package/dist/generated/assets/i18n/messagebundle_uk.json +1 -1
  101. package/dist/generated/assets/i18n/messagebundle_vi.json +1 -1
  102. package/dist/generated/assets/i18n/messagebundle_zh_CN.json +1 -1
  103. package/dist/generated/assets/i18n/messagebundle_zh_TW.json +1 -1
  104. package/dist/generated/i18n/i18n-defaults.d.ts +2 -1
  105. package/dist/generated/i18n/i18n-defaults.js +2 -1
  106. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  107. package/dist/generated/themes/ShellBar.css.d.ts +1 -1
  108. package/dist/generated/themes/ShellBar.css.js +1 -1
  109. package/dist/generated/themes/ShellBar.css.js.map +1 -1
  110. package/dist/generated/themes/ShellBarItem.css.d.ts +2 -0
  111. package/dist/generated/themes/ShellBarItem.css.js +8 -0
  112. package/dist/generated/themes/ShellBarItem.css.js.map +1 -0
  113. package/dist/generated/themes/ShellBarLegacy.css.d.ts +2 -0
  114. package/dist/generated/themes/ShellBarLegacy.css.js +8 -0
  115. package/dist/generated/themes/ShellBarLegacy.css.js.map +1 -0
  116. package/dist/generated/themes/ShellBarSearchLegacy.css.d.ts +2 -0
  117. package/dist/generated/themes/ShellBarSearchLegacy.css.js +8 -0
  118. package/dist/generated/themes/ShellBarSearchLegacy.css.js.map +1 -0
  119. package/dist/shellbar/IShellBarSearchController.d.ts +28 -0
  120. package/dist/shellbar/IShellBarSearchController.js +2 -0
  121. package/dist/shellbar/IShellBarSearchController.js.map +1 -0
  122. package/dist/shellbar/ShellBarAccessibility.d.ts +42 -0
  123. package/dist/shellbar/ShellBarAccessibility.js +50 -0
  124. package/dist/shellbar/ShellBarAccessibility.js.map +1 -0
  125. package/dist/shellbar/ShellBarItemNavigation.d.ts +18 -0
  126. package/dist/shellbar/ShellBarItemNavigation.js +86 -0
  127. package/dist/shellbar/ShellBarItemNavigation.js.map +1 -0
  128. package/dist/shellbar/ShellBarLegacy.d.ts +46 -0
  129. package/dist/shellbar/ShellBarLegacy.js +138 -0
  130. package/dist/shellbar/ShellBarLegacy.js.map +1 -0
  131. package/dist/shellbar/ShellBarOverflow.d.ts +51 -0
  132. package/dist/shellbar/ShellBarOverflow.js +159 -0
  133. package/dist/shellbar/ShellBarOverflow.js.map +1 -0
  134. package/dist/shellbar/ShellBarSearch.d.ts +59 -0
  135. package/dist/shellbar/ShellBarSearch.js +145 -0
  136. package/dist/shellbar/ShellBarSearch.js.map +1 -0
  137. package/dist/shellbar/ShellBarSearchLegacy.d.ts +65 -0
  138. package/dist/shellbar/ShellBarSearchLegacy.js +116 -0
  139. package/dist/shellbar/ShellBarSearchLegacy.js.map +1 -0
  140. package/dist/shellbar/templates/ShellBarLegacyTemplate.d.ts +20 -0
  141. package/dist/shellbar/templates/ShellBarLegacyTemplate.js +71 -0
  142. package/dist/shellbar/templates/ShellBarLegacyTemplate.js.map +1 -0
  143. package/dist/shellbar/templates/ShellBarSearchLegacyTemplate.d.ts +5 -0
  144. package/dist/shellbar/templates/ShellBarSearchLegacyTemplate.js +18 -0
  145. package/dist/shellbar/templates/ShellBarSearchLegacyTemplate.js.map +1 -0
  146. package/dist/shellbar/templates/ShellBarSearchTemplate.d.ts +4 -0
  147. package/dist/shellbar/templates/ShellBarSearchTemplate.js +17 -0
  148. package/dist/shellbar/templates/ShellBarSearchTemplate.js.map +1 -0
  149. package/dist/vscode.html-custom-data.json +29 -79
  150. package/dist/web-types.json +75 -239
  151. package/package.json +8 -8
  152. package/src/ShellBarItemTemplate.tsx +36 -0
  153. package/src/ShellBarTemplate.tsx +222 -300
  154. package/src/UserMenuTemplate.tsx +11 -3
  155. package/src/i18n/messagebundle.properties +3 -0
  156. package/src/i18n/messagebundle_ar.properties +2 -0
  157. package/src/i18n/messagebundle_bg.properties +6 -4
  158. package/src/i18n/messagebundle_ca.properties +2 -0
  159. package/src/i18n/messagebundle_cnr.properties +2 -0
  160. package/src/i18n/messagebundle_cs.properties +2 -0
  161. package/src/i18n/messagebundle_cy.properties +2 -0
  162. package/src/i18n/messagebundle_da.properties +2 -0
  163. package/src/i18n/messagebundle_de.properties +2 -0
  164. package/src/i18n/messagebundle_el.properties +2 -0
  165. package/src/i18n/messagebundle_en.properties +2 -0
  166. package/src/i18n/messagebundle_en_GB.properties +2 -0
  167. package/src/i18n/messagebundle_en_US_sappsd.properties +2 -0
  168. package/src/i18n/messagebundle_en_US_saprigi.properties +2 -0
  169. package/src/i18n/messagebundle_en_US_saptrc.properties +2 -0
  170. package/src/i18n/messagebundle_es.properties +2 -0
  171. package/src/i18n/messagebundle_es_MX.properties +2 -0
  172. package/src/i18n/messagebundle_et.properties +2 -0
  173. package/src/i18n/messagebundle_fi.properties +2 -0
  174. package/src/i18n/messagebundle_fr.properties +2 -0
  175. package/src/i18n/messagebundle_fr_CA.properties +2 -0
  176. package/src/i18n/messagebundle_hi.properties +2 -0
  177. package/src/i18n/messagebundle_hr.properties +2 -0
  178. package/src/i18n/messagebundle_hu.properties +2 -0
  179. package/src/i18n/messagebundle_id.properties +3 -1
  180. package/src/i18n/messagebundle_it.properties +2 -0
  181. package/src/i18n/messagebundle_iw.properties +2 -0
  182. package/src/i18n/messagebundle_ja.properties +2 -0
  183. package/src/i18n/messagebundle_kk.properties +2 -0
  184. package/src/i18n/messagebundle_ko.properties +2 -0
  185. package/src/i18n/messagebundle_lt.properties +2 -0
  186. package/src/i18n/messagebundle_lv.properties +2 -0
  187. package/src/i18n/messagebundle_mk.properties +2 -0
  188. package/src/i18n/messagebundle_ms.properties +2 -0
  189. package/src/i18n/messagebundle_nl.properties +2 -0
  190. package/src/i18n/messagebundle_no.properties +2 -0
  191. package/src/i18n/messagebundle_pl.properties +2 -0
  192. package/src/i18n/messagebundle_pt.properties +2 -0
  193. package/src/i18n/messagebundle_pt_PT.properties +2 -0
  194. package/src/i18n/messagebundle_ro.properties +2 -0
  195. package/src/i18n/messagebundle_ru.properties +2 -0
  196. package/src/i18n/messagebundle_sh.properties +2 -0
  197. package/src/i18n/messagebundle_sk.properties +2 -0
  198. package/src/i18n/messagebundle_sl.properties +2 -0
  199. package/src/i18n/messagebundle_sr.properties +2 -0
  200. package/src/i18n/messagebundle_sv.properties +2 -0
  201. package/src/i18n/messagebundle_th.properties +2 -0
  202. package/src/i18n/messagebundle_tr.properties +2 -0
  203. package/src/i18n/messagebundle_uk.properties +2 -0
  204. package/src/i18n/messagebundle_vi.properties +2 -0
  205. package/src/i18n/messagebundle_zh_CN.properties +2 -0
  206. package/src/i18n/messagebundle_zh_TW.properties +2 -0
  207. package/src/shellbar/templates/ShellBarLegacyTemplate.tsx +190 -0
  208. package/src/shellbar/templates/ShellBarSearchLegacyTemplate.tsx +61 -0
  209. package/src/shellbar/templates/ShellBarSearchTemplate.tsx +40 -0
  210. package/src/themes/NavigationLayout.css +1 -0
  211. package/src/themes/ShellBar.css +189 -372
  212. package/src/themes/ShellBarItem.css +43 -0
  213. package/src/themes/ShellBarLegacy.css +174 -0
  214. package/src/themes/ShellBarSearchLegacy.css +44 -0
  215. package/dist/ShellBarPopoverTemplate.d.ts +0 -2
  216. package/dist/ShellBarPopoverTemplate.js +0 -9
  217. package/dist/ShellBarPopoverTemplate.js.map +0 -1
  218. package/src/ShellBarPopoverTemplate.tsx +0 -50
package/dist/ShellBar.js CHANGED
@@ -6,41 +6,61 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  var ShellBar_1;
8
8
  import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
9
- import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
9
+ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
10
10
  import property from "@ui5/webcomponents-base/dist/decorators/property.js";
11
11
  import slot from "@ui5/webcomponents-base/dist/decorators/slot-strict.js";
12
- import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
13
12
  import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
13
+ import query from "@ui5/webcomponents-base/dist/decorators/query.js";
14
14
  import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js";
15
15
  import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
16
16
  import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
17
- import { isSpace, isEnter, isLeft, isRight, isHome, isEnd, } from "@ui5/webcomponents-base/dist/Keys.js";
18
- import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js";
19
- import { getTabbableElements } from "@ui5/webcomponents-base/dist/util/TabbableElements.js";
20
- import ListItemStandard from "@ui5/webcomponents/dist/ListItemStandard.js";
21
- import List from "@ui5/webcomponents/dist/List.js";
22
- import Popover from "@ui5/webcomponents/dist/Popover.js";
17
+ import { getScopedVarName } from "@ui5/webcomponents-base/dist/CustomElementsScopeUtils.js";
18
+ import arraysAreEqual from "@ui5/webcomponents-base/dist/util/arraysAreEqual.js";
19
+ import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
20
+ import throttle from "@ui5/webcomponents-base/dist/util/throttle.js";
23
21
  import Button from "@ui5/webcomponents/dist/Button.js";
24
22
  import ButtonBadge from "@ui5/webcomponents/dist/ButtonBadge.js";
25
- import Menu from "@ui5/webcomponents/dist/Menu.js";
26
23
  import Icon from "@ui5/webcomponents/dist/Icon.js";
27
- import { isDesktop, isPhone } from "@ui5/webcomponents-base/dist/Device.js";
28
- import search from "@ui5/webcomponents-icons/dist/search.js";
29
- import da from "@ui5/webcomponents-icons/dist/da.js";
30
- import bell from "@ui5/webcomponents-icons/dist/bell.js";
31
- import overflow from "@ui5/webcomponents-icons/dist/overflow.js";
32
- import grid from "@ui5/webcomponents-icons/dist/grid.js";
33
- import throttle from "@ui5/webcomponents-base/dist/util/throttle.js";
34
- import getActiveElement from "@ui5/webcomponents-base/dist/util/getActiveElement.js";
35
- // Templates
24
+ import Popover from "@ui5/webcomponents/dist/Popover.js";
25
+ import Menu from "@ui5/webcomponents/dist/Menu.js";
26
+ import List from "@ui5/webcomponents/dist/List.js";
27
+ import ListItemStandard from "@ui5/webcomponents/dist/ListItemStandard.js";
28
+ import searchIcon from "@ui5/webcomponents-icons/dist/search.js";
29
+ import bellIcon from "@ui5/webcomponents-icons/dist/bell.js";
30
+ import gridIcon from "@ui5/webcomponents-icons/dist/grid.js";
31
+ import daIcon from "@ui5/webcomponents-icons/dist/da.js";
32
+ import overflowIcon from "@ui5/webcomponents-icons/dist/overflow.js";
36
33
  import ShellBarTemplate from "./ShellBarTemplate.js";
37
- // Styles
38
34
  import shellBarStyles from "./generated/themes/ShellBar.css.js";
39
35
  import ShellBarPopoverCss from "./generated/themes/ShellBarPopover.css.js";
40
- import { SHELLBAR_LABEL, SHELLBAR_LOGO, SHELLBAR_NOTIFICATIONS, SHELLBAR_NOTIFICATIONS_NO_COUNT, SHELLBAR_CANCEL, SHELLBAR_PROFILE, SHELLBAR_PRODUCTS, SHELLBAR_SEARCH, SHELLBAR_SEARCH_FIELD, SHELLBAR_OVERFLOW, SHELLBAR_LOGO_AREA, SHELLBAR_ADDITIONAL_CONTEXT, SHELLBAR_SEARCHFIELD_DESCRIPTION, SHELLBAR_SEARCH_BTN_OPEN, SHELLBAR_PRODUCT_SWITCH_BTN, SHELLBAR_IMAGE_BTN, } from "./generated/i18n/i18n-defaults.js";
41
- const RESIZE_THROTTLE_RATE = 200; // ms
36
+ import shellBarLegacyStyles from "./generated/themes/ShellBarLegacy.css.js";
37
+ import ShellBarLegacy from "./shellbar/ShellBarLegacy.js";
38
+ import ShellBarSearch from "./shellbar/ShellBarSearch.js";
39
+ import ShellBarSearchLegacy from "./shellbar/ShellBarSearchLegacy.js";
40
+ import ShellBarOverflow from "./shellbar/ShellBarOverflow.js";
41
+ import ShellBarAccessibility from "./shellbar/ShellBarAccessibility.js";
42
+ import ShellBarItemNavigation from "./shellbar/ShellBarItemNavigation.js";
43
+ import ShellBarItem from "./ShellBarItem.js";
44
+ import ShellBarSpacer from "./ShellBarSpacer.js";
45
+ import { SHELLBAR_LABEL, SHELLBAR_NOTIFICATIONS, SHELLBAR_NOTIFICATIONS_NO_COUNT, SHELLBAR_PROFILE, SHELLBAR_PRODUCTS, SHELLBAR_SEARCH, SHELLBAR_ASSISTANT, SHELLBAR_OVERFLOW, SHELLBAR_ADDITIONAL_CONTEXT, } from "./generated/i18n/i18n-defaults.js";
42
46
  // actions always visible in lean mode, order is important
43
- const PREDEFINED_PLACE_ACTIONS = ["feedback", "sys-help"];
47
+ const PREDEFINED_PLACE_ITEMS = ["feedback", "sys-help"];
48
+ const ShellBarActions = {
49
+ Search: "search",
50
+ Profile: "profile",
51
+ Overflow: "overflow",
52
+ Assistant: "assistant",
53
+ ProductSwitch: "products",
54
+ Notifications: "notifications",
55
+ };
56
+ const ShellBarActionsSelectors = {
57
+ Search: ".ui5-shellbar-search-toggle",
58
+ Profile: ".ui5-shellbar-image-button",
59
+ Overflow: ".ui5-shellbar-overflow-button",
60
+ Assistant: ".ui5-shellbar-assistant-button",
61
+ ProductSwitch: ".ui5-shellbar-button-product-switch",
62
+ Notifications: ".ui5-shellbar-bell-button",
63
+ };
44
64
  /**
45
65
  * @class
46
66
  * ### Overview
@@ -74,42 +94,8 @@ const PREDEFINED_PLACE_ACTIONS = ["feedback", "sys-help"];
74
94
  * @since 0.8.0
75
95
  */
76
96
  let ShellBar = ShellBar_1 = class ShellBar extends UI5Element {
77
- static get FIORI_3_BREAKPOINTS() {
78
- return [
79
- 599,
80
- 1023,
81
- 1439,
82
- 1919,
83
- 10000,
84
- ];
85
- }
86
- static get FIORI_3_BREAKPOINTS_MAP() {
87
- return {
88
- "599": "S",
89
- "1023": "M",
90
- "1439": "L",
91
- "1919": "XL",
92
- "10000": "XXL",
93
- };
94
- }
95
97
  constructor() {
96
- super();
97
- /**
98
- * Defines the visibility state of the search button.
99
- *
100
- * **Note:** The `hideSearchButton` property is in an experimental state and is a subject to change.
101
- * @default false
102
- * @public
103
- */
104
- this.hideSearchButton = false;
105
- /**
106
- * Disables the automatic search field expansion/collapse when the available space is not enough.
107
- *
108
- * **Note:** The `disableSearchCollapse` property is in an experimental state and is a subject to change.
109
- * @default false
110
- * @public
111
- */
112
- this.disableSearchCollapse = false;
98
+ super(...arguments);
113
99
  /**
114
100
  * Defines, if the notification icon would be displayed.
115
101
  * @default false
@@ -170,465 +156,473 @@ let ShellBar = ShellBar_1 = class ShellBar extends UI5Element {
170
156
  */
171
157
  this.breakpointSize = "S";
172
158
  /**
159
+ * Actions computed from controllers.
160
+ * @private
161
+ */
162
+ this.actions = [];
163
+ /**
164
+ * Show overflow button when items are hidden.
165
+ * @private
166
+ */
167
+ this.showOverflowButton = false;
168
+ /**
169
+ * Open state of the overflow popover.
170
+ * @private
171
+ */
172
+ this.overflowPopoverOpen = false;
173
+ /**
174
+ * IDs of items currently hidden due to overflow.
175
+ * Used to trigger rerender for conditional rendering.
176
+ * @private
177
+ */
178
+ this.hiddenItemsIds = [];
179
+ /**
180
+ * Show full-screen search overlay.
173
181
  * @private
174
182
  */
175
- this.withLogo = false;
176
- this._itemsInfo = [];
177
- this._contentInfo = [];
178
- this._menuPopoverExpanded = false;
179
- this._overflowPopoverExpanded = false;
180
183
  this.showFullWidthSearch = false;
181
- this._cachedHiddenContent = [];
182
- this._lastOffsetWidth = 0;
183
- this._observableContent = [];
184
- this._autoRestoreSearchField = false;
185
- this._onSearchOpenBound = this._onSearchOpen.bind(this);
186
- this._onSearchCloseBound = this._onSearchClose.bind(this);
187
- this._onSearchBound = this._onSearch.bind(this);
188
- this._hiddenIcons = [];
189
- this._isInitialRendering = true;
190
- this._overflowNotifications = null;
191
- // marks if preventDefault() is called in item's press handler
192
- this._defaultItemPressPrevented = false;
193
- this.contentItemsObserver = new MutationObserver(() => {
194
- this._handleActionsOverflow();
195
- });
196
- this._headerPress = () => {
197
- if (this.hasMenuItems) {
198
- const menuPopover = this._getMenuPopover();
199
- menuPopover.opener = this.shadowRoot.querySelector(".ui5-shellbar-menu-button");
200
- menuPopover.open = true;
201
- }
184
+ this.RESIZE_THROTTLE_RATE = 100; // ms
185
+ this.handleResizeBound = throttle(this.handleResize.bind(this), this.RESIZE_THROTTLE_RATE);
186
+ this.breakpoints = [599, 1023, 1439, 1919, 10000];
187
+ this.breakpointMap = {
188
+ 599: "S",
189
+ 1023: "M",
190
+ 1439: "L",
191
+ 1919: "XL",
192
+ 10000: "XXL",
202
193
  };
203
- this._handleResize = throttle(() => {
204
- this.menuPopover = this._getMenuPopover();
205
- this.overflowPopover = this._getOverflowPopover();
206
- this.overflowPopover.open = false;
207
- if (this._lastOffsetWidth !== this.offsetWidth) {
208
- this._overflowActions();
209
- if (this.autoSearchField) {
210
- this._updateSearchFieldState();
211
- }
212
- }
213
- }, RESIZE_THROTTLE_RATE);
214
- }
215
- _onSearchOpen(e) {
216
- if (e.target !== this.search) {
217
- this._detachSearchFieldListeners(e.target);
218
- return;
219
- }
220
- if (isPhone()) {
221
- this.setSearchState(true);
222
- }
223
- }
224
- _onSearchClose(e) {
225
- if (e.target !== this.search) {
226
- this._detachSearchFieldListeners(e.target);
227
- return;
228
- }
229
- if (isPhone()) {
230
- this.setSearchState(false);
231
- }
232
- }
233
- _onSearch(e) {
234
- if (e.target !== this.search) {
235
- this._detachSearchFieldListeners(e.target);
236
- return;
237
- }
238
- // Decide when to toggle the search field:
239
- // - On mobile, the search opens on its own (we don’t interfere).
240
- // - If there’s already a value, onSearch is responsible for triggering the search (we don’t interfere)
241
- // - If the field is closed, we must open it regardless.
242
- if (isPhone() || (this.search?.value && this.showSearchField)) {
243
- return;
244
- }
245
- this.setSearchState(!this.showSearchField);
246
- }
247
- _updateSearchFieldState() {
248
- const spacerWidth = this.shadowRoot.querySelector(".ui5-shellbar-spacer") ? this.shadowRoot.querySelector(".ui5-shellbar-spacer").getBoundingClientRect().width : 0;
249
- const searchFieldWidth = this.domCalculatedValues("--_ui5_shellbar_search_field_width");
250
- if (this.showFullWidthSearch) {
251
- this.setSearchState(true);
252
- return;
253
- }
254
- if ((spacerWidth <= searchFieldWidth && this.contentItemsHidden.length !== 0) && this.showSearchField) {
255
- this.setSearchState(false);
256
- this._autoRestoreSearchField = true;
257
- }
258
- else if (spacerWidth > searchFieldWidth && this._autoRestoreSearchField) {
259
- this.setSearchState(true);
260
- this._autoRestoreSearchField = false;
261
- }
262
- }
263
- _onKeyDown(e) {
264
- if (!isLeft(e) && !isRight(e) && !isHome(e) && !isEnd(e)) {
265
- return;
266
- }
267
- const domRef = this.getDomRef();
268
- if (!domRef) {
269
- // If the component is not rendered yet, we should not handle the keydown event
270
- return;
271
- }
272
- const activeElement = getActiveElement();
273
- if (!activeElement) {
274
- return;
275
- }
276
- // Check if the active elements should "steal" the navigation
277
- if (this._allowChildNavigation(activeElement, e)) {
278
- return;
279
- }
280
- const items = getTabbableElements(domRef).filter(el => this._isVisible(el));
281
- const currentIndex = items.findIndex(el => el === activeElement);
282
- // Only handle arrow navigation if the focus is on a ShellBar item
283
- if (currentIndex !== -1) {
284
- e.preventDefault();
285
- // Focus navigation based on the key pressed
286
- if (isLeft(e)) {
287
- this._focusPreviousItem(items, currentIndex);
288
- }
289
- else if (isRight(e)) {
290
- this._focusNextItem(items, currentIndex);
291
- }
292
- else if (isHome(e)) {
293
- // Move focus to the first ShellBar item
294
- items[0]?.focus();
295
- }
296
- else if (isEnd(e)) {
297
- // Move focus to the last ShellBar item
298
- items[items.length - 1]?.focus();
299
- }
300
- }
301
- }
302
- _allowChildNavigation(activeElement, e) {
303
- if (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA") {
304
- return this._allowInputNavigation(activeElement, e);
305
- }
306
- return false; // Default to false for other elements
307
- }
308
- _allowInputNavigation(inputElement, e) {
309
- const cursorPosition = inputElement.selectionStart || 0;
310
- const textLength = inputElement.value.length;
311
- // Allow internal navigation if cursor is not at the boundaries
312
- if ((isLeft(e) && cursorPosition > 0)
313
- || (isRight(e) && cursorPosition < textLength)) {
314
- return true;
315
- }
316
- // Let ShellBar handle navigation if at boundaries
317
- return false;
318
- }
319
- _focusNextItem(items, currentIndex) {
320
- if (currentIndex < items.length - 1) {
321
- (items[currentIndex + 1]).focus(); // Focus the next element
322
- }
323
- }
324
- _focusPreviousItem(items, currentIndex) {
325
- if (currentIndex > 0) {
326
- (items[currentIndex - 1]).focus(); // Focus the previous element
327
- }
194
+ this.itemNavigation = new ShellBarItemNavigation({
195
+ getDomRef: () => this.getDomRef() || null,
196
+ });
197
+ this.overflow = new ShellBarOverflow();
198
+ this.accessibility = new ShellBarAccessibility();
199
+ this._searchAdaptor = new ShellBarSearch(this.getSearchDeps());
200
+ this._searchAdaptorLegacy = new ShellBarSearchLegacy({
201
+ ...this.getSearchDeps(),
202
+ getDisableSearchCollapse: () => this.disableSearchCollapse,
203
+ });
204
+ /* =================== Legacy Members =================== */
205
+ /**
206
+ * Defines the visibility state of the search button.
207
+ *
208
+ * **Note:** The `hideSearchButton` property is in an experimental state and is a subject to change.
209
+ * @default false
210
+ * @public
211
+ */
212
+ this.hideSearchButton = false;
213
+ /**
214
+ * Disables the automatic search field expansion/collapse when the available space is not enough.
215
+ *
216
+ * **Note:** The `disableSearchCollapse` property is in an experimental state and is a subject to change.
217
+ * @default false
218
+ * @public
219
+ */
220
+ this.disableSearchCollapse = false;
221
+ /**
222
+ * Open state of the menu popover (legacy).
223
+ * @private
224
+ */
225
+ this.menuPopoverOpen = false;
328
226
  }
329
- _isVisible(element) {
330
- const style = getComputedStyle(element);
331
- return style.display !== "none" && style.visibility !== "hidden" && element.offsetWidth > 0 && element.offsetHeight > 0;
227
+ /* =================== Lifecycle Methods =================== */
228
+ onEnterDOM() {
229
+ ResizeHandler.register(this, this.handleResizeBound);
230
+ this.searchAdaptor?.subscribe();
332
231
  }
333
- _getRightChildItems() {
334
- return [
335
- ...this.searchField,
336
- ...this.shadowRoot.querySelectorAll(".ui5-shellbar-search-item-for-arrow-nav"),
337
- ...this.assistant,
338
- ...this.shadowRoot.querySelectorAll(".ui5-shellbar-items-for-arrow-nav"),
339
- ];
232
+ onExitDOM() {
233
+ ResizeHandler.deregister(this, this.handleResizeBound);
234
+ this.searchAdaptor?.unsubscribe();
340
235
  }
341
- _menuItemPress(e) {
342
- const shouldContinue = this.fireDecoratorEvent("menu-item-click", {
343
- item: e.detail.item,
344
- });
345
- if (shouldContinue) {
346
- this.menuPopover.open = false;
236
+ onBeforeRendering() {
237
+ if (!this.legacyAdaptor) {
238
+ this.initLegacyController();
347
239
  }
348
- }
349
- _logoPress() {
350
- this.fireDecoratorEvent("logo-click", {
351
- targetRef: this.shadowRoot.querySelector(".ui5-shellbar-logo"),
240
+ // Sync branding breakpoint state
241
+ this.branding.forEach(brandingEl => {
242
+ brandingEl._isSBreakPoint = this.isSBreakPoint;
352
243
  });
244
+ this.buildActions();
245
+ this.searchAdaptor?.syncShowSearchFieldState();
246
+ // subscribe to search adaptor for cases when search is added dynamically
247
+ this.searchAdaptor?.unsubscribe();
248
+ this.searchAdaptor?.subscribe();
353
249
  }
354
- _menuPopoverBeforeOpen() {
355
- this._menuPopoverExpanded = true;
356
- if (this.menuPopover.content && this.menuPopover.content.length) {
357
- this.menuPopover.content[0].focusFirstItem();
358
- }
359
- }
360
- _menuPopoverAfterClose() {
361
- this._menuPopoverExpanded = false;
250
+ onAfterRendering() {
251
+ this.updateBreakpoint();
252
+ this.updateOverflow();
362
253
  }
363
- _overflowPopoverBeforeOpen() {
364
- this._overflowPopoverExpanded = true;
365
- if (this.overflowPopover.content && this.overflowPopover.content.length) {
366
- this.overflowPopover.content[0].focusFirstItem();
367
- }
254
+ /* =================== Actions Management =================== */
255
+ buildActions() {
256
+ this.actions = [
257
+ {
258
+ id: ShellBarActions.Search,
259
+ icon: searchIcon,
260
+ enabled: this.enabledFeatures.search,
261
+ selector: ShellBarActionsSelectors.Search,
262
+ isProtected: false,
263
+ stableDomRef: "toggle-search",
264
+ },
265
+ {
266
+ id: ShellBarActions.Assistant,
267
+ icon: daIcon,
268
+ enabled: this.enabledFeatures.assistant,
269
+ selector: ShellBarActionsSelectors.Assistant,
270
+ isProtected: false,
271
+ },
272
+ {
273
+ id: ShellBarActions.Notifications,
274
+ icon: bellIcon,
275
+ count: this.notificationsCount,
276
+ enabled: this.enabledFeatures.notifications,
277
+ selector: ShellBarActionsSelectors.Notifications,
278
+ isProtected: false,
279
+ stableDomRef: "notifications",
280
+ },
281
+ {
282
+ id: ShellBarActions.Overflow,
283
+ icon: overflowIcon,
284
+ enabled: this.enabledFeatures.overflow,
285
+ selector: ShellBarActionsSelectors.Overflow,
286
+ isProtected: true,
287
+ stableDomRef: "overflow",
288
+ },
289
+ {
290
+ id: ShellBarActions.Profile,
291
+ enabled: this.enabledFeatures.profile,
292
+ selector: ShellBarActionsSelectors.Profile,
293
+ isProtected: true,
294
+ stableDomRef: "profile",
295
+ },
296
+ {
297
+ id: ShellBarActions.ProductSwitch,
298
+ icon: gridIcon,
299
+ enabled: this.enabledFeatures.productSwitch,
300
+ selector: ShellBarActionsSelectors.ProductSwitch,
301
+ isProtected: true,
302
+ stableDomRef: "product-switch",
303
+ },
304
+ ].filter(action => action.enabled);
305
+ }
306
+ getAction(actionId) {
307
+ return this.actions.find(action => action.id === actionId);
308
+ }
309
+ getActionOverflowText(actionId) {
310
+ const texts = {
311
+ [ShellBarActions.Search]: this.texts.search,
312
+ [ShellBarActions.Profile]: this.texts.profile,
313
+ [ShellBarActions.Overflow]: this.texts.overflow,
314
+ [ShellBarActions.Assistant]: this.texts.assistant,
315
+ [ShellBarActions.ProductSwitch]: this.texts.products,
316
+ [ShellBarActions.Notifications]: this.texts.notificationsNoCount,
317
+ };
318
+ return texts[actionId] || actionId;
368
319
  }
369
- _overflowPopoverAfterClose() {
370
- this._overflowPopoverExpanded = false;
320
+ /* =================== Breakpoint Management =================== */
321
+ get isSBreakPoint() {
322
+ return this.breakpointSize === "S";
371
323
  }
372
- _logoKeyup(e) {
373
- if (isSpace(e)) {
374
- this._logoPress();
324
+ updateBreakpoint() {
325
+ const width = this.getBoundingClientRect().width;
326
+ const bp = this.breakpoints.find(b => width <= b) || 10000;
327
+ const breakpoint = this.breakpointMap[bp];
328
+ if (this.breakpointSize !== breakpoint) {
329
+ this.breakpointSize = breakpoint;
375
330
  }
376
331
  }
377
- _logoKeydown(e) {
378
- if (isSpace(e)) {
379
- e.preventDefault();
332
+ /* =================== Overflow Management =================== */
333
+ updateOverflow() {
334
+ if (!this.overflow) {
380
335
  return;
381
336
  }
382
- if (isEnter(e)) {
383
- this._logoPress();
384
- }
385
- }
386
- _calculateCSSREMValue(styleSet, propertyName) {
387
- return Number(styleSet.getPropertyValue(propertyName).replace("rem", "")) * parseInt(getComputedStyle(document.body).getPropertyValue("font-size"));
388
- }
389
- domCalculatedValues(cssVar) {
390
- const shellbarComputerStyle = getComputedStyle(this.getDomRef());
391
- return this._calculateCSSREMValue(shellbarComputerStyle, cssVar); // px
392
- }
393
- onBeforeRendering() {
394
- this.withLogo = this.hasLogo;
395
- this._hiddenIcons = this._itemsInfo.filter(info => {
396
- const isHidden = (info.classes.indexOf("ui5-shellbar-hidden-button") !== -1);
397
- const isSet = info.classes.indexOf("ui5-shellbar-invisible-button") === -1;
398
- const isOverflowIcon = info.classes.indexOf("ui5-shellbar-overflow-button") !== -1;
399
- const isImageIcon = info.classes.indexOf("ui5-shellbar-image-button") !== -1;
400
- const shouldStayOnScreen = isOverflowIcon || (isImageIcon && this.hasProfile);
401
- return isHidden && isSet && !shouldStayOnScreen;
337
+ const result = this.overflow.updateOverflow({
338
+ actions: this.actions,
339
+ content: this.sortContent(this.content),
340
+ customItems: this.sortItems(this.items),
341
+ hiddenItemsIds: this.hiddenItemsIds,
342
+ showSearchField: this.enabledFeatures.search && this.showSearchField,
343
+ overflowOuter: this.overflowOuter,
344
+ overflowInner: this.overflowInner,
345
+ setVisible: (selector, visible) => {
346
+ const element = this.shadowRoot.querySelector(selector);
347
+ if (element) {
348
+ element.classList[visible ? "remove" : "add"]("ui5-shellbar-hidden");
349
+ }
350
+ },
402
351
  });
403
- this._observeContentItems();
404
- // search field shouldn't be expanded initially in full width mode
405
- if (this.showFullWidthSearch && this._isInitialRendering) {
406
- this.setSearchState(false);
407
- this._autoRestoreSearchField = true;
408
- }
409
- if (isSelfCollapsibleSearch(this.search)) {
410
- if (isPhone()) {
411
- this.search.open = this.showSearchField;
352
+ this.handleUpdateOverflowResult(result);
353
+ return result.hiddenItemsIds;
354
+ }
355
+ handleUpdateOverflowResult(result) {
356
+ const { hiddenItemsIds, showOverflowButton } = result;
357
+ // Update items overflow state
358
+ this.items.forEach(item => {
359
+ item.inOverflow = hiddenItemsIds.includes(item._id);
360
+ if (item.inOverflow) {
361
+ // clear the hidden class to ensure the item is visible in the overflow popover
362
+ item.classList.remove("ui5-shellbar-hidden");
412
363
  }
413
- else {
414
- this.search.collapsed = !this.showSearchField;
415
- }
416
- this._detachSearchFieldListeners(this.search);
417
- this._attachSearchFieldListeners(this.search);
364
+ });
365
+ if (!arraysAreEqual(this.hiddenItemsIds, hiddenItemsIds)) {
366
+ this.handleContentVisibilityChanged(this.hiddenItemsIds, hiddenItemsIds);
367
+ this.hiddenItemsIds = hiddenItemsIds;
368
+ this.showOverflowButton = showOverflowButton;
369
+ }
370
+ this.showFullWidthSearch = this.searchAdaptor?.shouldShowFullScreen() || false;
371
+ }
372
+ handleContentVisibilityChanged(oldHiddenItemsIds, newHiddenItemsIds) {
373
+ const filterContentIds = (ids) => ids.filter(id => this.content.some(item => item._individualSlot === id));
374
+ const oldHiddenContentIds = filterContentIds(oldHiddenItemsIds);
375
+ const newHiddenContentIds = filterContentIds(newHiddenItemsIds);
376
+ if (!arraysAreEqual(oldHiddenContentIds, newHiddenContentIds)) {
377
+ this.fireDecoratorEvent("content-item-visibility-change", {
378
+ items: newHiddenContentIds.map(id => this.content.find(item => item._individualSlot === id)),
379
+ });
418
380
  }
419
381
  }
420
- /**
421
- * Use this method to change the state of the search filed according to internal logic.
422
- * An event is fired to notify the change.
423
- */
424
- async setSearchState(expanded) {
425
- if (expanded === this.showSearchField) {
426
- return;
427
- }
428
- this.showSearchField = expanded;
429
- await renderFinished();
430
- this.fireDecoratorEvent("search-field-toggle", { expanded });
382
+ handleResize() {
383
+ this.overflowPopoverOpen = false;
384
+ this.updateBreakpoint();
385
+ const hiddenItemsIds = this.updateOverflow() ?? [];
386
+ const spacerWidth = this.spacer?.getBoundingClientRect().width || 0;
387
+ this.searchAdaptor?.autoManageSearchState(hiddenItemsIds.length, spacerWidth);
431
388
  }
432
- onAfterRendering() {
433
- this._lastOffsetWidth = this.offsetWidth;
434
- this._overflowActions();
435
- this.onInitialRendering();
389
+ isHidden(itemId) {
390
+ return this.hiddenItemsIds.includes(itemId);
436
391
  }
437
- async onInitialRendering() {
438
- if (this._isInitialRendering) {
439
- await renderFinished();
440
- if (this.autoSearchField) {
441
- this._updateSearchFieldState();
442
- }
443
- }
444
- this._isInitialRendering = false;
392
+ handleOverflowClick() {
393
+ this.overflowPopoverOpen = !this.overflowPopoverOpen;
394
+ }
395
+ onPopoverClose() {
396
+ this.overflowPopoverOpen = false;
445
397
  }
446
398
  /**
447
- * Closes the overflow area.
448
- * Useful to manually close the overflow after having suppressed automatic closing with preventDefault() of ShellbarItem's press event
399
+ * Closes the overflow popover.
449
400
  * @public
450
401
  */
451
402
  closeOverflow() {
452
- if (this.overflowPopover) {
453
- this.overflowPopover.open = false;
454
- }
403
+ this.overflowPopoverOpen = false;
455
404
  }
456
- _handleBarBreakpoints() {
457
- const width = this.getBoundingClientRect().width;
458
- const breakpoints = ShellBar_1.FIORI_3_BREAKPOINTS;
459
- const size = breakpoints.find(bp1 => width <= bp1) || ShellBar_1.FIORI_3_BREAKPOINTS[ShellBar_1.FIORI_3_BREAKPOINTS.length - 1];
460
- const mappedSize = ShellBar_1.FIORI_3_BREAKPOINTS_MAP[size];
461
- if (this.breakpointSize !== mappedSize) {
462
- this.breakpointSize = mappedSize;
405
+ handleOverflowItemClick(e) {
406
+ const target = e.target;
407
+ const actionId = target.getAttribute("data-action-id");
408
+ let prevented = e.defaultPrevented; // for custom actions
409
+ if (actionId === ShellBarActions.Notifications) {
410
+ prevented = this.handleNotificationsClick();
411
+ }
412
+ else if (actionId === ShellBarActions.Search) {
413
+ prevented = this.handleSearchButtonClick();
414
+ }
415
+ if (!prevented) {
416
+ this.overflowPopoverOpen = false;
463
417
  }
464
- this.branding.forEach(brandingEl => {
465
- brandingEl._isSBreakPoint = this.isSBreakPoint;
466
- });
467
- }
468
- _hideItems(items) {
469
- items.forEach(item => {
470
- if (item.classes.indexOf("ui5-shellbar-no-overflow-button") === -1) {
471
- item.classes = `${item.classes} ui5-shellbar-hidden-button`;
472
- }
473
- });
474
- return items;
475
418
  }
476
- _resetItemsVisibility(items) {
477
- items.forEach(item => {
478
- item.classList.remove("ui5-shellbar-hidden-button");
419
+ get overflowItems() {
420
+ return this.overflow.getOverflowItems({
421
+ actions: this.actions,
422
+ customItems: this.sortItems(this.items),
423
+ hiddenItemsIds: this.hiddenItemsIds,
479
424
  });
480
425
  }
481
- _handleActionsOverflow() {
482
- const inner = this.overflowInner;
483
- const wrapper = this.overflowWrapper;
484
- const hidableDomElements = this.hidableDomElements;
485
- const hiddenItems = [];
486
- let lastHiddenIndex = 0;
487
- this._resetItemsVisibility(hidableDomElements);
488
- for (let i = 0; i < hidableDomElements.length; i++) {
489
- if (inner?.offsetWidth === wrapper?.offsetWidth) {
490
- lastHiddenIndex = i;
491
- break;
492
- }
493
- const item = hidableDomElements[i];
494
- hiddenItems.push(item.id);
495
- item.classList.add("ui5-shellbar-hidden-button");
426
+ /**
427
+ * Returns badge text for overflow button.
428
+ * Shows count if only one item with count is overflowed, otherwise shows attention dot.
429
+ */
430
+ get overflowBadge() {
431
+ const itemsWithCount = this.overflowItems.filter(item => item.data.count);
432
+ if (itemsWithCount.length === 1) {
433
+ return itemsWithCount[0].data.count;
496
434
  }
497
- if (hiddenItems.length === 1 && !this.showSearchField) {
498
- const nextItemToHide = hidableDomElements[++lastHiddenIndex];
499
- if (nextItemToHide) {
500
- hiddenItems.push(nextItemToHide.id);
501
- }
435
+ if (itemsWithCount.length > 1) {
436
+ return " "; // Attention dot
502
437
  }
503
- const itemsInfo = this._getItemsInfo().filter(item => item.show && item.classes.indexOf("ui5-shellbar-no-overflow-button") === -1);
504
- const contentInfo = this._getContentInfo().sort((a, b) => a.hideOrder - b.hideOrder);
505
- const itemsToHide = [...itemsInfo, ...contentInfo].filter(item => hiddenItems.includes(item.id));
506
- this._hideItems(itemsToHide);
507
- return { itemsInfo, contentInfo };
438
+ return undefined;
508
439
  }
509
- _overflowActions() {
510
- this._handleBarBreakpoints();
511
- const { itemsInfo, contentInfo } = this._handleActionsOverflow();
512
- this._updateItemsInfo(itemsInfo);
513
- this._updateContentInfo(contentInfo);
514
- this._updateOverflowNotifications();
515
- this.showFullWidthSearch = this.overflowed && this.showSearchField;
516
- }
517
- _toggleActionPopover() {
518
- const overflowButton = this.shadowRoot.querySelector(".ui5-shellbar-overflow-button");
519
- const overflowPopover = this._getOverflowPopover();
520
- overflowPopover.opener = overflowButton;
521
- overflowPopover.open = true;
440
+ /* =================== Search Management =================== */
441
+ get search() {
442
+ return this.searchField.length ? this.searchField[0] : null;
522
443
  }
523
- onEnterDOM() {
524
- ResizeHandler.register(this, this._handleResize);
525
- if (isDesktop()) {
526
- this.setAttribute("desktop", "");
444
+ get isSelfCollapsibleSearch() {
445
+ const searchField = this.search;
446
+ if (searchField) {
447
+ return "collapsed" in searchField && "open" in searchField;
527
448
  }
528
- this._attachSearchFieldListeners(this.search);
529
- }
530
- onExitDOM() {
531
- this.contentItemsObserver.disconnect();
532
- this._observableContent = [];
533
- ResizeHandler.deregister(this, this._handleResize);
534
- this._detachSearchFieldListeners(this.search);
449
+ return false;
535
450
  }
536
- _attachSearchFieldListeners(searchField) {
537
- if (!searchField) {
538
- return;
539
- }
540
- searchField.addEventListener("ui5-open", this._onSearchOpenBound);
541
- searchField.addEventListener("ui5-close", this._onSearchCloseBound);
542
- searchField.addEventListener("ui5-search", this._onSearchBound);
451
+ getSearchDeps() {
452
+ return {
453
+ getSearchField: () => this.search,
454
+ getSearchState: () => this.enabledFeatures.search && this.showSearchField,
455
+ getCSSVariable: (cssVar) => this.getCSSVariable(cssVar),
456
+ setSearchState: (expanded) => this.setSearchState(expanded),
457
+ getOverflowed: () => this.overflow.isOverflowing(this.overflowOuter, this.overflowInner),
458
+ };
543
459
  }
544
- _detachSearchFieldListeners(searchField) {
545
- if (!searchField) {
546
- return;
460
+ get searchAdaptor() {
461
+ if (this.isSelfCollapsibleSearch) {
462
+ return this._searchAdaptor;
547
463
  }
548
- searchField.removeEventListener("ui5-open", this._onSearchOpenBound);
549
- searchField.removeEventListener("ui5-close", this._onSearchCloseBound);
550
- searchField.removeEventListener("ui5-search", this._onSearchBound);
464
+ return this._searchAdaptorLegacy;
551
465
  }
552
- _handleSearchIconPress() {
553
- const searchButtonRef = this.shadowRoot.querySelector(".ui5-shellbar-search-button");
466
+ handleSearchButtonClick() {
467
+ const searchButton = this.shadowRoot.querySelector(".ui5-shellbar-search-button");
554
468
  const defaultPrevented = !this.fireDecoratorEvent("search-button-click", {
555
- targetRef: searchButtonRef,
469
+ targetRef: searchButton,
556
470
  searchFieldVisible: this.showSearchField,
557
471
  });
558
472
  if (defaultPrevented) {
559
- return;
473
+ return defaultPrevented;
560
474
  }
561
475
  this.setSearchState(!this.showSearchField);
562
476
  if (!this.showSearchField) {
563
- return;
477
+ return defaultPrevented;
564
478
  }
565
479
  const input = this.searchField[0];
566
- // update the state immediately
567
480
  if (input) {
568
481
  input.focused = true;
569
- }
570
- // move the focus later
571
- setTimeout(() => {
572
- if (input) {
482
+ setTimeout(() => {
573
483
  input.focus();
574
- }
575
- }, 100);
484
+ }, 100);
485
+ }
486
+ return defaultPrevented;
576
487
  }
577
- async _handleActionListClick() {
578
- if (!this._defaultItemPressPrevented) {
579
- this.closeOverflow();
580
- // wait for DOM to be updated when ui5-popover is closed, otherwise if Enter key is hold
581
- // there will be no visual indication that this has happened
582
- await renderFinished();
488
+ async setSearchState(expanded) {
489
+ if (expanded === this.showSearchField) {
490
+ return;
583
491
  }
584
- this._defaultItemPressPrevented = false;
492
+ this.showSearchField = expanded;
493
+ await renderFinished();
494
+ this.fireDecoratorEvent("search-field-toggle", { expanded });
585
495
  }
586
- _handleCustomActionPress(e) {
587
- const target = e.target;
588
- const refItemId = target.getAttribute("data-ui5-external-action-item-id");
589
- if (refItemId) {
590
- const shellbarItem = this.items.find(item => {
591
- return item._id === refItemId;
496
+ handleCancelButtonClick() {
497
+ const cancelBtn = this.shadowRoot.querySelector(".ui5-shellbar-cancel-button");
498
+ if (!cancelBtn) {
499
+ return;
500
+ }
501
+ const clearDefaultPrevented = !this.fireDecoratorEvent("search-field-clear", {
502
+ targetRef: cancelBtn,
503
+ });
504
+ this.showFullWidthSearch = false;
505
+ this.setSearchState(false);
506
+ if (!clearDefaultPrevented && this.search) {
507
+ this.search.value = "";
508
+ }
509
+ }
510
+ /* =================== Legacy Features Management =================== */
511
+ initLegacyController() {
512
+ if (this.hasLegacyFeatures) {
513
+ this.legacyAdaptor = new ShellBarLegacy({
514
+ component: this,
515
+ getShadowRoot: () => this.shadowRoot,
592
516
  });
593
- const prevented = shellbarItem.fireClickEvent(e);
594
- this._defaultItemPressPrevented = prevented;
595
517
  }
596
518
  }
597
- _handleOverflowPress() {
598
- this._toggleActionPopover();
519
+ get hasLegacyFeatures() {
520
+ return this.logo.length > 0
521
+ || !!this.primaryTitle
522
+ || !!this.secondaryTitle
523
+ || this.menuItems.length > 0;
599
524
  }
600
- _handleNotificationsPress(e) {
601
- const notificationIconRef = this.shadowRoot.querySelector(".ui5-shellbar-bell-button"), target = e.target;
602
- this._defaultItemPressPrevented = !this.fireDecoratorEvent("notifications-click", {
603
- targetRef: notificationIconRef.classList.contains("ui5-shellbar-hidden-button") ? target : notificationIconRef,
604
- });
525
+ /* =================== Keyboard Navigation =================== */
526
+ _onKeyDown(e) {
527
+ this.itemNavigation.handleKeyDown(e);
528
+ }
529
+ /* =================== Content Management =================== */
530
+ get startContent() {
531
+ return this.splitContent(this.content).start;
605
532
  }
606
- _handleProfilePress() {
607
- this.fireDecoratorEvent("profile-click", {
608
- targetRef: this.shadowRoot.querySelector(".ui5-shellbar-image-button"),
533
+ get endContent() {
534
+ return this.splitContent(this.content).end;
535
+ }
536
+ get separatorConfig() {
537
+ const { start, end } = this.splitContent(this.content);
538
+ return {
539
+ showStartSeparator: start.some(item => !this.hiddenItemsIds.includes(item._individualSlot)),
540
+ showEndSeparator: end.some(item => !this.hiddenItemsIds.includes(item._individualSlot)),
541
+ };
542
+ }
543
+ splitContent(content) {
544
+ const spacerIndex = content.findIndex(child => child.hasAttribute("ui5-shellbar-spacer"));
545
+ if (spacerIndex === -1) {
546
+ return { start: [...content], end: [] };
547
+ }
548
+ return {
549
+ start: content.slice(0, spacerIndex),
550
+ end: content.slice(spacerIndex + 1),
551
+ };
552
+ }
553
+ sortContent(content) {
554
+ // reverse so items on the right are hidden first
555
+ // then sort by hide order to apply custom preferences
556
+ return content.toReversed().toSorted((a, b) => {
557
+ const aOrder = parseInt(a.getAttribute("data-hide-order") || "0");
558
+ const bOrder = parseInt(b.getAttribute("data-hide-order") || "0");
559
+ return aOrder - bOrder;
609
560
  });
610
561
  }
611
- _handleCancelButtonPress() {
612
- const cancelButtonRef = this.shadowRoot.querySelector(".ui5-shellbar-cancel-button");
613
- const clearDefaultPrevented = !this.fireDecoratorEvent("search-field-clear", {
614
- targetRef: cancelButtonRef,
562
+ /*
563
+ * Determines whether a separator should be packed with an item.
564
+ * Separators are packed with the last item that is hidden to account for
565
+ * the space they occupy when next overflow calculation occurs.
566
+ */
567
+ getPackedSeparatorInfo(item, isStartGroup) {
568
+ const group = isStartGroup ? this.startContent : this.endContent;
569
+ const sorted = this.sortContent(group);
570
+ const isHidden = this.hiddenItemsIds.includes(item._individualSlot);
571
+ const isLastItem = sorted.at(-1) === item;
572
+ return { shouldPack: isHidden && isLastItem };
573
+ }
574
+ /* =================== Items Management =================== */
575
+ sortItems(items) {
576
+ return items.toSorted((a, b) => {
577
+ const aIndex = PREDEFINED_PLACE_ITEMS.indexOf(a.icon || "");
578
+ const bIndex = PREDEFINED_PLACE_ITEMS.indexOf(b.icon || "");
579
+ return aIndex - bIndex;
615
580
  });
616
- this.showFullWidthSearch = false;
617
- this.setSearchState(false);
618
- if (!clearDefaultPrevented) {
619
- this._clearSearchFieldValue();
620
- }
621
581
  }
622
- _handleProductSwitchPress(e) {
623
- const buttonRef = this.shadowRoot.querySelector(".ui5-shellbar-button-product-switch"), target = e.target;
624
- this._defaultItemPressPrevented = !this.fireDecoratorEvent("product-switch-click", {
625
- targetRef: buttonRef.classList.contains("ui5-shellbar-hidden-button") ? target : buttonRef,
582
+ /* =================== Accessibility =================== */
583
+ get actionsAccessibilityInfo() {
584
+ return this.accessibility.getActionsAccessibilityAttributes(this.texts, {
585
+ overflowPopoverOpen: this.overflowPopoverOpen,
586
+ accessibilityAttributes: this.accessibilityAttributes,
626
587
  });
627
588
  }
628
- _clearSearchFieldValue() {
629
- if (this.search) {
630
- this.search.value = "";
631
- }
589
+ get actionsRole() {
590
+ const visibleCount = this.actions.filter(a => !this.hiddenItemsIds.includes(a.id)).length;
591
+ return this.accessibility.getActionsRole(visibleCount);
592
+ }
593
+ get contentRole() {
594
+ const visibleItemsCount = this.content.filter(item => !this.hiddenItemsIds.includes(item._individualSlot)).length;
595
+ return this.accessibility.getContentRole(visibleItemsCount);
596
+ }
597
+ /* =================== Common Members =================== */
598
+ get enabledFeatures() {
599
+ return {
600
+ search: this.searchField.length > 0,
601
+ profile: this.profile.length > 0,
602
+ content: this.content.length > 0,
603
+ branding: this.branding.length > 0,
604
+ overflow: this.showOverflowButton,
605
+ assistant: this.assistant.length > 0,
606
+ startButton: this.startButton.length > 0,
607
+ notifications: this.showNotifications,
608
+ productSwitch: this.showProductSwitch,
609
+ };
610
+ }
611
+ get texts() {
612
+ return {
613
+ search: ShellBar_1.i18nBundle.getText(SHELLBAR_SEARCH),
614
+ profile: ShellBar_1.i18nBundle.getText(SHELLBAR_PROFILE),
615
+ shellbar: ShellBar_1.i18nBundle.getText(SHELLBAR_LABEL),
616
+ products: ShellBar_1.i18nBundle.getText(SHELLBAR_PRODUCTS),
617
+ overflow: ShellBar_1.i18nBundle.getText(SHELLBAR_OVERFLOW),
618
+ assistant: ShellBar_1.i18nBundle.getText(SHELLBAR_ASSISTANT),
619
+ notifications: ShellBar_1.i18nBundle.getText(SHELLBAR_NOTIFICATIONS, this.notificationsCount || 0),
620
+ notificationsNoCount: ShellBar_1.i18nBundle.getText(SHELLBAR_NOTIFICATIONS_NO_COUNT),
621
+ contentItems: this.content.length > 1 ? ShellBar_1.i18nBundle.getText(SHELLBAR_ADDITIONAL_CONTEXT) : undefined,
622
+ };
623
+ }
624
+ get popoverHorizontalAlign() {
625
+ return this.effectiveDir === "rtl" ? "Start" : "End";
632
626
  }
633
627
  /**
634
628
  * Returns the `logo` DOM ref.
@@ -676,514 +670,51 @@ let ShellBar = ShellBar_1 = class ShellBar extends UI5Element {
676
670
  return this.shadowRoot.querySelector(`*[data-ui5-stable="product-switch"]`);
677
671
  }
678
672
  /**
679
- * Returns the `search` icon DOM ref.
680
- * @returns The search icon DOM ref
673
+ * Returns the search button DOM reference.
681
674
  * @public
682
- * @since 2.10.0
683
675
  */
684
676
  async getSearchButtonDomRef() {
685
677
  await renderFinished();
686
678
  return this.shadowRoot.querySelector(`*[data-ui5-stable="toggle-search"]`);
687
679
  }
688
- _getContentInfo() {
689
- return [
690
- ...this.contentItemsSorted.map(item => {
691
- return {
692
- hideOrder: parseInt(item.getAttribute("data-hide-order") || "0"),
693
- id: item.slot,
694
- classes: "ui5-shellbar-content-item",
695
- show: false,
696
- };
697
- }),
698
- ];
699
- }
700
- /**
701
- * Returns all items that will be placed in the right of the bar as icons / dom elements.
702
- */
703
- _getItemsInfo() {
704
- const items = [
705
- {
706
- icon: search,
707
- text: this._searchText,
708
- classes: `${this.searchField.length ? "" : "ui5-shellbar-invisible-button"} ui5-shellbar-search-button ui5-shellbar-button`,
709
- id: `${this._id}-item-${1}`,
710
- press: this._handleSearchIconPress.bind(this),
711
- show: !!this.searchField.length,
712
- tooltip: this._searchText,
713
- },
714
- {
715
- icon: da,
716
- text: "Assistant",
717
- classes: `${this.assistant.length ? "" : "ui5-shellbar-invisible-button"} ui5-shellbar-assistant-button`,
718
- id: `${this._id}-assistant`,
719
- show: !!this.assistant.length,
720
- press: () => { },
721
- tooltip: this.assistant.length ? (this.assistant[0].getAttribute("text") || this.assistant[0].getAttribute("title") || undefined) : undefined,
722
- },
723
- {
724
- icon: bell,
725
- title: this._notificationsText,
726
- text: ShellBar_1.i18nBundle.getText(SHELLBAR_NOTIFICATIONS_NO_COUNT),
727
- count: this.notificationsCount,
728
- classes: `${this.showNotifications ? "" : "ui5-shellbar-invisible-button"} ui5-shellbar-bell-button ui5-shellbar-button`,
729
- id: `${this._id}-item-${2}`,
730
- show: this.showNotifications,
731
- press: this._handleNotificationsPress.bind(this),
732
- tooltip: this._notificationsText,
733
- },
734
- // sort feedback and help to always be last
735
- ...this.items.sort((a, b) => {
736
- const aIndex = PREDEFINED_PLACE_ACTIONS.indexOf(a.icon || "");
737
- const bIndex = PREDEFINED_PLACE_ACTIONS.indexOf(b.icon || "");
738
- return aIndex - bIndex;
739
- }).map((item) => {
740
- item._getRealDomRef = () => this.shadowRoot.querySelector(`*[data-ui5-stable=${item.stableDomRef}]`);
741
- // check if included for lean mode
742
- const show = !!item.icon || false;
743
- return {
744
- icon: item.icon,
745
- id: item._id,
746
- count: item.count || undefined,
747
- refItemid: item._id,
748
- text: item.text,
749
- classes: "ui5-shellbar-custom-item ui5-shellbar-button",
750
- show,
751
- press: this._handleCustomActionPress.bind(this),
752
- custom: true,
753
- title: item.title,
754
- stableDomRef: item.stableDomRef,
755
- tooltip: item.title || item.text,
756
- accessibilityAttributes: item.accessibilityAttributes,
757
- };
758
- }),
759
- {
760
- icon: overflow,
761
- text: "Overflow",
762
- classes: "ui5-shellbar-hidden-button ui5-shellbar-no-overflow-button ui5-shellbar-overflow-button ui5-shellbar-button",
763
- id: `${this.id}-item-${5}`,
764
- press: this._handleOverflowPress.bind(this),
765
- show: true,
766
- tooltip: this._overflowText,
767
- },
768
- {
769
- text: "Person",
770
- classes: `${this.hasProfile ? "" : "ui5-shellbar-invisible-button"} ui5-shellbar-no-overflow-button ui5-shellbar-image-button ui5-shellbar-button`,
771
- profile: true,
772
- id: `${this._id}-item-${3}`,
773
- show: this.hasProfile,
774
- press: this._handleProfilePress.bind(this),
775
- tooltip: this._profileText,
776
- },
777
- {
778
- icon: grid,
779
- text: this._productsText,
780
- classes: `${this.showProductSwitch ? "" : "ui5-shellbar-invisible-button"} ui5-shellbar-no-overflow-button ui5-shellbar-button ui5-shellbar-image-button ui5-shellbar-button-product-switch`,
781
- id: `${this._id}-item-${4}`,
782
- show: this.showProductSwitch,
783
- press: this._handleProductSwitchPress.bind(this),
784
- tooltip: this._productsText,
785
- },
786
- ];
787
- return items;
788
- }
789
- _updateItemsInfo(newItemsInfo) {
790
- const isDifferent = JSON.stringify(this._itemsInfo) !== JSON.stringify(newItemsInfo);
791
- if (isDifferent) {
792
- this._itemsInfo = newItemsInfo;
793
- }
794
- }
795
- _updateContentInfo(newContentInfo) {
796
- const isDifferent = JSON.stringify(this._contentInfo) !== JSON.stringify(newContentInfo);
797
- if (isDifferent) {
798
- this._contentInfo = newContentInfo;
799
- this._fireContentItemVisibilityChangeEvent();
800
- }
801
- }
802
- _fireContentItemVisibilityChangeEvent() {
803
- const hiddenByClass = this._contentInfo
804
- .filter(item => item.classes.indexOf("ui5-shellbar-hidden-button") !== -1)
805
- .map(item => item.id);
806
- this.fireDecoratorEvent("content-item-visibility-change", {
807
- items: this.contentItems.filter(item => hiddenByClass.includes(item.slot)),
808
- });
809
- }
810
- _updateOverflowNotifications() {
811
- const notificationsArr = [];
812
- let overflowNotifications = null;
813
- this._itemsInfo.forEach(item => {
814
- if (item.count && item.classes.includes("ui5-shellbar-hidden-button")) {
815
- notificationsArr.push(item.count);
816
- }
817
- });
818
- if (notificationsArr.length === 1) {
819
- overflowNotifications = notificationsArr[0];
820
- }
821
- else if (notificationsArr.length > 1) {
822
- overflowNotifications = " ";
823
- }
824
- this._overflowNotifications = overflowNotifications;
825
- }
826
- _observeContentItems() {
827
- if (this.hasMatchingContent) {
828
- return;
829
- }
830
- this.contentItems.forEach(item => {
831
- if (!this._observableContent.includes(item)) {
832
- this.contentItemsObserver.observe(item, {
833
- characterData: false,
834
- childList: false,
835
- subtree: false,
836
- attributes: true,
837
- attributeFilter: ["data-hide-order"],
838
- });
839
- }
840
- });
841
- this._observableContent = this.contentItems;
842
- }
843
- _getOverflowPopover() {
844
- return this.shadowRoot.querySelector(".ui5-shellbar-overflow-popover");
845
- }
846
- _getMenuPopover() {
847
- return this.shadowRoot.querySelector(".ui5-shellbar-menu-popover");
848
- }
849
- isIconHidden(name) {
850
- const itemInfo = this._itemsInfo.find(item => item.icon === name);
851
- if (!itemInfo) {
852
- return false;
853
- }
854
- return itemInfo.classes.indexOf("ui5-shellbar-hidden-button") !== -1;
855
- }
856
- get hasMatchingContent() {
857
- if (this._observableContent.length !== this.contentItems.length) {
858
- return false;
859
- }
860
- const observableContentSet = new WeakSet(this._observableContent);
861
- return this.contentItems.every(item => observableContentSet.has(item));
862
- }
863
- get contentItemsSorted() {
864
- return this.contentItems.toReversed().sort((a, b) => {
865
- return parseInt(a.getAttribute("data-hide-order") || "0") - parseInt(b.getAttribute("data-hide-order") || "0");
866
- });
867
- }
868
- get contentItemsWrappersSorted() {
869
- return this.contentItemsSorted.map(item => this.shadowRoot.querySelector(`#${item.slot}`)).filter(item => item !== null);
870
- }
871
- get autoSearchField() {
872
- const onFocus = document.activeElement === this.searchField[0];
873
- const hasValue = this.searchField[0]?.value?.length > 0;
874
- const disableSearchCollapse = this.disableSearchCollapse || onFocus || hasValue;
875
- if (disableSearchCollapse) {
876
- return false;
877
- }
878
- return this.showSearchField || this._autoRestoreSearchField;
879
- }
880
- get startContentInfoSorted() {
881
- return this._contentInfo
882
- .filter(item => this.startContent.find(contentItem => contentItem.slot === item.id))
883
- .sort((a, b) => a.hideOrder - b.hideOrder);
884
- }
885
- get endContentInfoSorted() {
886
- return this._contentInfo
887
- .filter(item => this.endContent.find(contentItem => contentItem.slot === item.id))
888
- .sort((a, b) => a.hideOrder - b.hideOrder);
680
+ _fireClickEvent(eventName, domRef) {
681
+ return domRef ? !this.fireDecoratorEvent(eventName, { targetRef: domRef }) : false;
889
682
  }
890
- get showStartSeparator() {
891
- return this.startContentInfoSorted.some(item => !item.classes.includes("ui5-shellbar-hidden-button"));
683
+ handleNotificationsClick() {
684
+ return this._fireClickEvent("notifications-click", this.notificationsDomRef);
892
685
  }
893
- get showEndSeparator() {
894
- return this.endContentInfoSorted.some(item => !item.classes.includes("ui5-shellbar-hidden-button"));
686
+ handleProfileClick() {
687
+ return this._fireClickEvent("profile-click", this.profileDomRef);
895
688
  }
896
- shouldIncludeSeparator(itemInfo, contentInfo) {
897
- // once the last item from the start/end content was hidden, the
898
- // separator is "packed" with it in order to account for any next measurements
899
- if (!itemInfo) {
900
- return false;
901
- }
902
- const lastVisibleItem = contentInfo.at(-1);
903
- return lastVisibleItem?.id === itemInfo.id && itemInfo.classes.indexOf("ui5-shellbar-hidden-button") > -1;
689
+ handleProductSwitchClick() {
690
+ return this._fireClickEvent("product-switch-click", this.productSwitchDomRef);
904
691
  }
905
- get classes() {
906
- return {
907
- wrapper: {
908
- "ui5-shellbar-root": true,
909
- "ui5-shellbar-with-searchfield": this.hasSearchField,
910
- },
911
- button: {
912
- "ui5-shellbar-menu-button--interactive": this.hasMenuItems,
913
- },
914
- notification: {
915
- "ui5-shellbar-hidden-button": this.isIconHidden("bell"),
916
- },
917
- search: {
918
- "ui5-shellbar-hidden-button": this.isIconHidden("search"),
919
- "ui5-shellbar-search-toggle": true,
920
- },
921
- overflow: {
922
- "ui5-shellbar-hidden-button": this._hiddenIcons.length === 0,
923
- },
924
- assistant: {
925
- "ui5-shellbar-hidden-button": this.isIconHidden("assistant"),
926
- "ui5-shellbar-assistant-button": true,
927
- },
928
- searchField: {
929
- "ui5-shellbar-search-field": this.showSearchField,
930
- "ui5-shellbar-search-toggle": isSelfCollapsibleSearch(this.search),
931
- "ui5-shellbar-hidden-button": !this.showSearchField,
932
- },
933
- };
934
- }
935
- get styles() {
936
- const styles = {
937
- "display": this.showSearchField ? "flex" : "none",
938
- };
939
- return {
940
- searchField: isSelfCollapsibleSearch(this.search) ? {} : styles,
941
- };
942
- }
943
- get customItemsInfo() {
944
- return this._itemsInfo.filter(itemInfo => !!itemInfo.custom);
945
- }
946
- get hasLogo() {
947
- return !!this.logo.length;
948
- }
949
- get showLogoInMenuButton() {
950
- return this.hasLogo && (this.breakpointSize === "S");
951
- }
952
- get showTitleInMenuButton() {
953
- return this.primaryTitle && !(this.showLogoInMenuButton);
954
- }
955
- get showMenuButton() {
956
- return this.primaryTitle || this.showLogoInMenuButton;
957
- }
958
- get hasAssistant() {
959
- return !!this.assistant.length;
960
- }
961
- get hasBranding() {
962
- return !!this.branding.length;
963
- }
964
- get hasSearchField() {
965
- return !!this.searchField.length;
966
- }
967
- get hasMidContent() {
968
- return !!this.midContent.length;
969
- }
970
- get hasProfile() {
971
- return !!this.profile.length;
972
- }
973
- get hasMenuItems() {
974
- return this.menuItems.length > 0;
975
- }
976
- get imageBtnText() {
977
- return getEffectiveAriaLabelText(this) || ShellBar_1.i18nBundle.getText(SHELLBAR_IMAGE_BTN);
978
- }
979
- get _shellbarText() {
980
- return ShellBar_1.i18nBundle.getText(SHELLBAR_LABEL);
981
- }
982
- get _logoText() {
983
- return this.accessibilityAttributes.logo?.name || ShellBar_1.i18nBundle.getText(SHELLBAR_LOGO);
984
- }
985
- get _notificationsText() {
986
- return ShellBar_1.i18nBundle.getText(SHELLBAR_NOTIFICATIONS, this.notificationsCount || 0);
987
- }
988
- get _cancelBtnText() {
989
- return ShellBar_1.i18nBundle.getText(SHELLBAR_CANCEL);
990
- }
991
- get _logoAreaText() {
992
- const primaryTitle = this.primaryTitle ?? "";
993
- const secondaryTitle = this.secondaryTitle ?? "";
994
- return ShellBar_1.i18nBundle.getText(SHELLBAR_LOGO_AREA, primaryTitle, secondaryTitle);
995
- }
996
- get _contentItemsText() {
997
- return this._enableContentAreaAccessibility ? ShellBar_1.i18nBundle.getText(SHELLBAR_ADDITIONAL_CONTEXT) : undefined;
998
- }
999
- get _searchFieldDescription() {
1000
- return ShellBar_1.i18nBundle.getText(SHELLBAR_SEARCHFIELD_DESCRIPTION);
1001
- }
1002
- get _contentItemsRole() {
1003
- if (this._enableContentAreaAccessibility) {
1004
- return "group";
1005
- }
1006
- }
1007
- get _enableContentAreaAccessibility() {
1008
- return this.contentItems.length > 1;
1009
- }
1010
- get contentItems() {
1011
- return [...this.startContent, ...this.endContent];
1012
- }
1013
- get startContent() {
1014
- // all items before the first spacer
1015
- const spacerIndex = this.content.findIndex(child => child.hasAttribute("ui5-shellbar-spacer"));
1016
- if (spacerIndex === -1) {
1017
- return this.content;
1018
- }
1019
- return this.content.slice(0, spacerIndex);
1020
- }
1021
- get endContent() {
1022
- // all items after the first spacer
1023
- const spacerIndex = this.content.findIndex(child => child.hasAttribute("ui5-shellbar-spacer"));
1024
- if (spacerIndex === -1) {
1025
- return [];
1026
- }
1027
- return this.content.slice(spacerIndex + 1);
1028
- }
1029
- get _rightChildRole() {
1030
- const items = this._getRightChildItems();
1031
- const visibleItems = items.filter(item => {
1032
- return this._isVisible(item);
1033
- });
1034
- if (visibleItems.length === 1) {
1035
- return;
1036
- }
1037
- return "toolbar";
1038
- }
1039
- get _searchFieldText() {
1040
- return ShellBar_1.i18nBundle.getText(SHELLBAR_SEARCH_FIELD);
1041
- }
1042
- get _searchBtnOpen() {
1043
- return ShellBar_1.i18nBundle.getText(SHELLBAR_SEARCH_BTN_OPEN);
1044
- }
1045
- get _productSwitchBtnText() {
1046
- return ShellBar_1.i18nBundle.getText(SHELLBAR_PRODUCT_SWITCH_BTN);
1047
- }
1048
- get _profileText() {
1049
- return this.accessibilityAttributes.profile?.name || ShellBar_1.i18nBundle.getText(SHELLBAR_PROFILE);
1050
- }
1051
- get _productsText() {
1052
- return ShellBar_1.i18nBundle.getText(SHELLBAR_PRODUCTS);
1053
- }
1054
- get _searchText() {
1055
- return ShellBar_1.i18nBundle.getText(SHELLBAR_SEARCH);
1056
- }
1057
- get _overflowText() {
1058
- return ShellBar_1.i18nBundle.getText(SHELLBAR_OVERFLOW);
1059
- }
1060
- get _brandingText() {
1061
- return this.accessibilityAttributes.branding?.name || this.primaryTitle;
1062
- }
1063
- get hasContentItems() {
1064
- return this.contentItems.length > 0;
1065
- }
1066
- get hidableDomElements() {
1067
- const items = Array.from(this.shadowRoot.querySelectorAll(".ui5-shellbar-button:not(.ui5-shellbar-search-button):not(.ui5-shellbar-overflow-button):not(.ui5-shellbar-cancel-button):not(.ui5-shellbar-no-overflow-button)"));
1068
- const assistant = this.shadowRoot.querySelector(".ui5-shellbar-assistant-button");
1069
- const searchToggle = this.shadowRoot.querySelector(".ui5-shellbar-search-toggle");
1070
- const contentItems = this.contentItemsWrappersSorted;
1071
- const firstContentItem = contentItems.pop();
1072
- const prioritizeContent = this.showSearchField && this.hasSearchField;
1073
- // order here is important for the responsive behavior, the items will be
1074
- // measured and hidden in the order they are returned until no overlap is detected
1075
- let itemsToHide = [];
1076
- if (prioritizeContent) {
1077
- // search field was toggled, the content items should make space for it
1078
- const overflowItems = [...items, assistant];
1079
- const visibleItems = overflowItems.filter(item => item && !item.classList.contains("ui5-shellbar-hidden-button"));
1080
- const hiddenItems = overflowItems.filter(item => item && item.classList.contains("ui5-shellbar-hidden-button"));
1081
- itemsToHide = [
1082
- ...hiddenItems,
1083
- ...contentItems,
1084
- firstContentItem,
1085
- ...visibleItems,
1086
- ];
1087
- }
1088
- else {
1089
- // search field is close, actions should go to the overflow first
1090
- itemsToHide = [
1091
- ...items.toReversed(),
1092
- assistant,
1093
- ...contentItems,
1094
- searchToggle,
1095
- firstContentItem,
1096
- ];
1097
- }
1098
- return itemsToHide.filter(Boolean);
1099
- }
1100
- get contentItemsHidden() {
1101
- return this.contentItemsWrappersSorted.filter(item => item.classList.contains("ui5-shellbar-hidden-button"));
1102
- }
1103
- get overflowWrapper() {
1104
- return this.shadowRoot.querySelector(".ui5-shellbar-overflow-container-right");
1105
- }
1106
- get overflowInner() {
1107
- return this.shadowRoot.querySelector(".ui5-shellbar-overflow-container-right-inner");
1108
- }
1109
- get overflowed() {
1110
- const wrapper = this.overflowWrapper;
1111
- const inner = this.overflowInner;
1112
- if (!wrapper || !inner) {
1113
- return false;
1114
- }
1115
- return inner.offsetWidth > wrapper.offsetWidth;
1116
- }
1117
- get accInfo() {
1118
- const overflowExpanded = this.accessibilityAttributes.overflow?.expanded;
1119
- return {
1120
- notifications: {
1121
- "title": this._notificationsText,
1122
- "accessibilityAttributes": {
1123
- expanded: this.accessibilityAttributes.notifications?.expanded,
1124
- hasPopup: this.accessibilityAttributes.notifications?.hasPopup,
1125
- },
1126
- },
1127
- profile: {
1128
- "title": this._profileText,
1129
- "accessibilityAttributes": {
1130
- hasPopup: this.accessibilityAttributes.profile?.hasPopup,
1131
- expanded: this.accessibilityAttributes.profile?.expanded,
1132
- },
1133
- },
1134
- products: {
1135
- "title": this._productsText,
1136
- "accessibilityAttributes": {
1137
- hasPopup: this.accessibilityAttributes.product?.hasPopup,
1138
- expanded: this.accessibilityAttributes.product?.expanded,
1139
- },
1140
- },
1141
- search: {
1142
- "title": this._searchText,
1143
- "accessibilityAttributes": {
1144
- hasPopup: this.accessibilityAttributes.search?.hasPopup,
1145
- },
1146
- },
1147
- overflow: {
1148
- "title": this._overflowText,
1149
- "accessibilityAttributes": {
1150
- hasPopup: this.accessibilityAttributes.overflow?.hasPopup || "menu",
1151
- expanded: overflowExpanded === undefined ? this._overflowPopoverExpanded : overflowExpanded,
1152
- },
1153
- },
1154
- branding: {
1155
- "title": this._brandingText,
1156
- "accessibilityAttributes": {
1157
- name: this.accessibilityAttributes.branding?.name,
1158
- },
1159
- },
1160
- };
1161
- }
1162
- get accLogoRole() {
1163
- return this.accessibilityAttributes.logo?.role || "link";
1164
- }
1165
- get isSBreakPoint() {
1166
- return this.breakpointSize === "S";
1167
- }
1168
- get hasSelfCollapsibleSearch() {
1169
- return isSelfCollapsibleSearch(this.search);
1170
- }
1171
- get search() {
1172
- return this.searchField.length ? this.searchField[0] : null;
692
+ getCSSVariable(cssVar) {
693
+ const styleSet = getComputedStyle(this.getDomRef());
694
+ return styleSet.getPropertyValue(getScopedVarName(cssVar));
1173
695
  }
1174
696
  };
1175
697
  __decorate([
1176
- property({ type: Boolean })
1177
- ], ShellBar.prototype, "hideSearchButton", void 0);
698
+ slot()
699
+ ], ShellBar.prototype, "startButton", void 0);
1178
700
  __decorate([
1179
- property({ type: Boolean })
1180
- ], ShellBar.prototype, "disableSearchCollapse", void 0);
701
+ slot()
702
+ ], ShellBar.prototype, "branding", void 0);
1181
703
  __decorate([
1182
- property()
1183
- ], ShellBar.prototype, "primaryTitle", void 0);
704
+ slot({ type: HTMLElement, individualSlots: true })
705
+ ], ShellBar.prototype, "content", void 0);
1184
706
  __decorate([
1185
- property()
1186
- ], ShellBar.prototype, "secondaryTitle", void 0);
707
+ slot({ type: HTMLElement })
708
+ ], ShellBar.prototype, "searchField", void 0);
709
+ __decorate([
710
+ slot()
711
+ ], ShellBar.prototype, "assistant", void 0);
712
+ __decorate([
713
+ slot({ type: HTMLElement, "default": true, individualSlots: true })
714
+ ], ShellBar.prototype, "items", void 0);
715
+ __decorate([
716
+ slot()
717
+ ], ShellBar.prototype, "profile", void 0);
1187
718
  __decorate([
1188
719
  property()
1189
720
  ], ShellBar.prototype, "notificationsCount", void 0);
@@ -1202,36 +733,42 @@ __decorate([
1202
733
  __decorate([
1203
734
  property()
1204
735
  ], ShellBar.prototype, "breakpointSize", void 0);
736
+ __decorate([
737
+ property({ type: Object })
738
+ ], ShellBar.prototype, "actions", void 0);
1205
739
  __decorate([
1206
740
  property({ type: Boolean })
1207
- ], ShellBar.prototype, "withLogo", void 0);
741
+ ], ShellBar.prototype, "showOverflowButton", void 0);
1208
742
  __decorate([
1209
- property({ type: Object })
1210
- ], ShellBar.prototype, "_itemsInfo", void 0);
743
+ property({ type: Boolean })
744
+ ], ShellBar.prototype, "overflowPopoverOpen", void 0);
1211
745
  __decorate([
1212
746
  property({ type: Object })
1213
- ], ShellBar.prototype, "_contentInfo", void 0);
747
+ ], ShellBar.prototype, "hiddenItemsIds", void 0);
1214
748
  __decorate([
1215
- property({ type: Boolean, noAttribute: true })
1216
- ], ShellBar.prototype, "_menuPopoverExpanded", void 0);
749
+ property({ type: Boolean })
750
+ ], ShellBar.prototype, "showFullWidthSearch", void 0);
1217
751
  __decorate([
1218
- property({ type: Boolean, noAttribute: true })
1219
- ], ShellBar.prototype, "_overflowPopoverExpanded", void 0);
752
+ query(".ui5-shellbar-spacer")
753
+ ], ShellBar.prototype, "spacer", void 0);
1220
754
  __decorate([
1221
- property({ type: Boolean, noAttribute: true })
1222
- ], ShellBar.prototype, "showFullWidthSearch", void 0);
755
+ query(".ui5-shellbar-overflow-container")
756
+ ], ShellBar.prototype, "overflowOuter", void 0);
1223
757
  __decorate([
1224
- slot()
1225
- ], ShellBar.prototype, "assistant", void 0);
758
+ query(".ui5-shellbar-overflow-container-inner")
759
+ ], ShellBar.prototype, "overflowInner", void 0);
1226
760
  __decorate([
1227
- slot()
1228
- ], ShellBar.prototype, "branding", void 0);
761
+ property({ type: Boolean })
762
+ ], ShellBar.prototype, "hideSearchButton", void 0);
1229
763
  __decorate([
1230
- slot({ type: HTMLElement, "default": true, invalidateOnChildChange: true })
1231
- ], ShellBar.prototype, "items", void 0);
764
+ property({ type: Boolean })
765
+ ], ShellBar.prototype, "disableSearchCollapse", void 0);
1232
766
  __decorate([
1233
- slot()
1234
- ], ShellBar.prototype, "profile", void 0);
767
+ property()
768
+ ], ShellBar.prototype, "primaryTitle", void 0);
769
+ __decorate([
770
+ property()
771
+ ], ShellBar.prototype, "secondaryTitle", void 0);
1235
772
  __decorate([
1236
773
  slot()
1237
774
  ], ShellBar.prototype, "logo", void 0);
@@ -1239,39 +776,33 @@ __decorate([
1239
776
  slot()
1240
777
  ], ShellBar.prototype, "menuItems", void 0);
1241
778
  __decorate([
1242
- slot({
1243
- type: HTMLElement,
1244
- invalidateOnChildChange: true,
1245
- })
1246
- ], ShellBar.prototype, "searchField", void 0);
1247
- __decorate([
1248
- slot()
1249
- ], ShellBar.prototype, "startButton", void 0);
779
+ property({ type: Boolean })
780
+ ], ShellBar.prototype, "menuPopoverOpen", void 0);
1250
781
  __decorate([
1251
782
  slot()
1252
783
  ], ShellBar.prototype, "midContent", void 0);
1253
- __decorate([
1254
- slot({ type: HTMLElement, individualSlots: true })
1255
- ], ShellBar.prototype, "content", void 0);
1256
784
  __decorate([
1257
785
  i18n("@ui5/webcomponents-fiori")
1258
786
  ], ShellBar, "i18nBundle", void 0);
1259
787
  ShellBar = ShellBar_1 = __decorate([
1260
788
  customElement({
1261
789
  tag: "ui5-shellbar",
1262
- fastNavigation: true,
1263
- languageAware: true,
790
+ styles: [shellBarStyles, shellBarLegacyStyles, ShellBarPopoverCss],
1264
791
  renderer: jsxRenderer,
1265
792
  template: ShellBarTemplate,
1266
- styles: [shellBarStyles, ShellBarPopoverCss],
793
+ fastNavigation: true,
794
+ languageAware: true,
1267
795
  dependencies: [
1268
- Button,
1269
796
  Icon,
1270
797
  List,
798
+ Button,
799
+ ButtonBadge,
1271
800
  Popover,
801
+ ShellBarSpacer,
802
+ ShellBarItem,
1272
803
  ListItemStandard,
804
+ // legacy dependencies
1273
805
  Menu,
1274
- ButtonBadge,
1275
806
  ],
1276
807
  })
1277
808
  /**
@@ -1379,12 +910,7 @@ ShellBar = ShellBar_1 = __decorate([
1379
910
  bubbles: true,
1380
911
  })
1381
912
  ], ShellBar);
1382
- const isSelfCollapsibleSearch = (searchField) => {
1383
- if (searchField) {
1384
- return "collapsed" in searchField && "open" in searchField;
1385
- }
1386
- return false;
1387
- };
1388
913
  ShellBar.define();
1389
914
  export default ShellBar;
915
+ export { ShellBarActions, ShellBarActionsSelectors, };
1390
916
  //# sourceMappingURL=ShellBar.js.map