@sapudex/web-components 2.46.0 → 2.48.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 (157) hide show
  1. package/cypress/specs/DatePicker.cy.tsx +62 -0
  2. package/cypress/specs/Tag.cy.tsx +34 -3
  3. package/cypress/specs/TextField.cy.tsx +68 -0
  4. package/dist/Carousel.d.ts +48 -3
  5. package/dist/Carousel.js +149 -7
  6. package/dist/Carousel.js.map +1 -1
  7. package/dist/CarouselTemplate.js +9 -2
  8. package/dist/CarouselTemplate.js.map +1 -1
  9. package/dist/DatePicker.d.ts +5 -0
  10. package/dist/DatePicker.js +10 -0
  11. package/dist/DatePicker.js.map +1 -1
  12. package/dist/DatePickerTemplate.js +1 -1
  13. package/dist/DatePickerTemplate.js.map +1 -1
  14. package/dist/MastheadItem.d.ts +7 -4
  15. package/dist/MastheadItem.js +6 -17
  16. package/dist/MastheadItem.js.map +1 -1
  17. package/dist/Tag.js +3 -2
  18. package/dist/Tag.js.map +1 -1
  19. package/dist/TagTemplate.js +2 -2
  20. package/dist/TagTemplate.js.map +1 -1
  21. package/dist/TextField.d.ts +12 -0
  22. package/dist/TextField.js +15 -0
  23. package/dist/TextField.js.map +1 -1
  24. package/dist/TextFieldTemplate.js +1 -1
  25. package/dist/TextFieldTemplate.js.map +1 -1
  26. package/dist/assets/{InputSuggestions-BwpJ8Exf.js → InputSuggestions-BcK6O4Bk.js} +1 -1
  27. package/dist/assets/{ListItemStandardExpandableTextTemplate-7iRPZq6L.js → ListItemStandardExpandableTextTemplate-u600dmHC.js} +1 -1
  28. package/dist/assets/{bundle.esm-BbkM4Bz9.js → bundle.esm-C6Ie2WeI.js} +230 -230
  29. package/dist/assets/messagebundle_en-DoNTK1BE.js +1 -0
  30. package/dist/assets/messagebundle_pl-CsXeN1y6.js +1 -0
  31. package/dist/assets/messagebundle_pt_PT-CQ5YAsmx.js +1 -0
  32. package/dist/css/themes/Badge.css +1 -1
  33. package/dist/css/themes/Carousel.css +1 -1
  34. package/dist/css/themes/ListItem.css +1 -1
  35. package/dist/css/themes/MastheadCountrySelector.css +1 -1
  36. package/dist/css/themes/MastheadItem.css +1 -1
  37. package/dist/css/themes/MastheadMenu.css +1 -1
  38. package/dist/css/themes/MastheadMobileMenu.css +1 -1
  39. package/dist/css/themes/MastheadProfileMenu.css +1 -1
  40. package/dist/css/themes/Table.css +1 -1
  41. package/dist/css/themes/TableCell.css +1 -1
  42. package/dist/css/themes/TableGroupRow.css +1 -1
  43. package/dist/css/themes/TableHeaderCell.css +1 -1
  44. package/dist/css/themes/Tag.css +1 -1
  45. package/dist/css/themes/Wizard.css +1 -1
  46. package/dist/css/themes/WizardTab.css +1 -1
  47. package/dist/custom-elements-internal.json +104 -0
  48. package/dist/custom-elements.json +90 -0
  49. package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
  50. package/dist/generated/assets/i18n/messagebundle_pl.json +1 -1
  51. package/dist/generated/assets/i18n/messagebundle_pt_PT.json +1 -1
  52. package/dist/generated/i18n/i18n-defaults.d.ts +3 -1
  53. package/dist/generated/i18n/i18n-defaults.js +3 -1
  54. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  55. package/dist/generated/templates/MastheadItemTemplate.lit.js +29 -26
  56. package/dist/generated/templates/MastheadItemTemplate.lit.js.map +1 -1
  57. package/dist/generated/themes/Badge.css.d.ts +1 -1
  58. package/dist/generated/themes/Badge.css.js +1 -1
  59. package/dist/generated/themes/Badge.css.js.map +1 -1
  60. package/dist/generated/themes/Carousel.css.d.ts +1 -1
  61. package/dist/generated/themes/Carousel.css.js +1 -1
  62. package/dist/generated/themes/Carousel.css.js.map +1 -1
  63. package/dist/generated/themes/ListItem.css.d.ts +1 -1
  64. package/dist/generated/themes/ListItem.css.js +1 -1
  65. package/dist/generated/themes/ListItem.css.js.map +1 -1
  66. package/dist/generated/themes/MastheadCountrySelector.css.d.ts +1 -1
  67. package/dist/generated/themes/MastheadCountrySelector.css.js +1 -1
  68. package/dist/generated/themes/MastheadCountrySelector.css.js.map +1 -1
  69. package/dist/generated/themes/MastheadItem.css.d.ts +1 -1
  70. package/dist/generated/themes/MastheadItem.css.js +1 -1
  71. package/dist/generated/themes/MastheadItem.css.js.map +1 -1
  72. package/dist/generated/themes/MastheadMenu.css.d.ts +1 -1
  73. package/dist/generated/themes/MastheadMenu.css.js +1 -1
  74. package/dist/generated/themes/MastheadMenu.css.js.map +1 -1
  75. package/dist/generated/themes/MastheadMobileMenu.css.d.ts +1 -1
  76. package/dist/generated/themes/MastheadMobileMenu.css.js +1 -1
  77. package/dist/generated/themes/MastheadMobileMenu.css.js.map +1 -1
  78. package/dist/generated/themes/MastheadProfileMenu.css.d.ts +1 -1
  79. package/dist/generated/themes/MastheadProfileMenu.css.js +1 -1
  80. package/dist/generated/themes/MastheadProfileMenu.css.js.map +1 -1
  81. package/dist/generated/themes/Table.css.d.ts +1 -1
  82. package/dist/generated/themes/Table.css.js +1 -1
  83. package/dist/generated/themes/Table.css.js.map +1 -1
  84. package/dist/generated/themes/TableCell.css.d.ts +1 -1
  85. package/dist/generated/themes/TableCell.css.js +1 -1
  86. package/dist/generated/themes/TableCell.css.js.map +1 -1
  87. package/dist/generated/themes/TableGroupRow.css.d.ts +1 -1
  88. package/dist/generated/themes/TableGroupRow.css.js +1 -1
  89. package/dist/generated/themes/TableGroupRow.css.js.map +1 -1
  90. package/dist/generated/themes/TableHeaderCell.css.d.ts +1 -1
  91. package/dist/generated/themes/TableHeaderCell.css.js +1 -1
  92. package/dist/generated/themes/TableHeaderCell.css.js.map +1 -1
  93. package/dist/generated/themes/Tag.css.d.ts +1 -1
  94. package/dist/generated/themes/Tag.css.js +1 -1
  95. package/dist/generated/themes/Tag.css.js.map +1 -1
  96. package/dist/generated/themes/Wizard.css.d.ts +1 -1
  97. package/dist/generated/themes/Wizard.css.js +1 -1
  98. package/dist/generated/themes/Wizard.css.js.map +1 -1
  99. package/dist/generated/themes/WizardTab.css.d.ts +1 -1
  100. package/dist/generated/themes/WizardTab.css.js +1 -1
  101. package/dist/generated/themes/WizardTab.css.js.map +1 -1
  102. package/dist/messagebundle.properties +3 -0
  103. package/dist/messagebundle_en.properties +2 -0
  104. package/dist/messagebundle_pl.properties +134 -1
  105. package/dist/messagebundle_pt_PT.properties +126 -1
  106. package/dist/vscode.html-custom-data.json +21 -1
  107. package/dist/web-types.json +50 -2
  108. package/package.json +1 -1
  109. package/src/Carousel.ts +180 -9
  110. package/src/CarouselTemplate.tsx +66 -27
  111. package/src/DatePicker.ts +9 -0
  112. package/src/DatePickerTemplate.tsx +2 -1
  113. package/src/MastheadItem.hbs +15 -0
  114. package/src/MastheadItem.ts +12 -21
  115. package/src/Tag.ts +3 -2
  116. package/src/TagTemplate.tsx +2 -0
  117. package/src/TextField.ts +26 -1
  118. package/src/TextFieldTemplate.tsx +1 -0
  119. package/src/generated/i18n/i18n-defaults.ts +2 -2
  120. package/src/generated/templates/MastheadItemTemplate.lit.ts +29 -26
  121. package/src/generated/themes/Badge.css.ts +1 -1
  122. package/src/generated/themes/Carousel.css.ts +1 -1
  123. package/src/generated/themes/ListItem.css.ts +1 -1
  124. package/src/generated/themes/MastheadCountrySelector.css.ts +1 -1
  125. package/src/generated/themes/MastheadItem.css.ts +1 -1
  126. package/src/generated/themes/MastheadMenu.css.ts +1 -1
  127. package/src/generated/themes/MastheadMobileMenu.css.ts +1 -1
  128. package/src/generated/themes/MastheadProfileMenu.css.ts +1 -1
  129. package/src/generated/themes/Table.css.ts +1 -1
  130. package/src/generated/themes/TableCell.css.ts +1 -1
  131. package/src/generated/themes/TableGroupRow.css.ts +1 -1
  132. package/src/generated/themes/TableHeaderCell.css.ts +1 -1
  133. package/src/generated/themes/Tag.css.ts +1 -1
  134. package/src/generated/themes/Wizard.css.ts +1 -1
  135. package/src/generated/themes/WizardTab.css.ts +1 -1
  136. package/src/i18n/messagebundle.properties +3 -0
  137. package/src/i18n/messagebundle_en.properties +2 -0
  138. package/src/i18n/messagebundle_pl.properties +134 -1
  139. package/src/i18n/messagebundle_pt_PT.properties +126 -1
  140. package/src/themes/Badge.css +3 -0
  141. package/src/themes/Carousel.css +20 -8
  142. package/src/themes/ListItem.css +3 -0
  143. package/src/themes/MastheadCountrySelector.css +4 -9
  144. package/src/themes/MastheadItem.css +45 -25
  145. package/src/themes/MastheadMenu.css +0 -2
  146. package/src/themes/MastheadMobileMenu.css +12 -0
  147. package/src/themes/MastheadProfileMenu.css +0 -15
  148. package/src/themes/Table.css +1 -1
  149. package/src/themes/TableCell.css +3 -3
  150. package/src/themes/TableGroupRow.css +1 -1
  151. package/src/themes/TableHeaderCell.css +3 -4
  152. package/src/themes/Tag.css +24 -0
  153. package/src/themes/Wizard.css +1 -0
  154. package/src/themes/WizardTab.css +16 -7
  155. package/dist/assets/messagebundle_en-BZqDcZHN.js +0 -1
  156. package/dist/assets/messagebundle_pl-BmaELnDD.js +0 -1
  157. package/dist/assets/messagebundle_pt_PT-DcVh6BH6.js +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
3
3
  "name": "@sapudex/web-components",
4
- "version": "2.46.0",
4
+ "version": "2.48.0",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -584,7 +584,7 @@
584
584
  },
585
585
  {
586
586
  "name": "udex-carousel",
587
- "description": "<h3 class=\"comment-api-title\">Overview</h3>\n\n\n<h3>Usage</h3>\n\nFor the <code>udex-carousel</code>\n<h3>ES6 Module Import</h3>\n\n<code>import \"@sapudex/web-components/dist/Carousel.js\";</code>\n---\n\n\n### **Events:**\n - **navigate** - Triggered when carousel navigates to a new slide\n\n### **Slots:**\n - **default** - Defines the content of the component.",
587
+ "description": "<h3 class=\"comment-api-title\">Overview</h3>\n\n\n<h3>Usage</h3>\n\nFor the <code>udex-carousel</code>\n<h3>ES6 Module Import</h3>\n\n<code>import \"@sapudex/web-components/dist/Carousel.js\";</code>\n---\n\n\n### **Events:**\n - **autoplay-toggle-click** - Fired event when the user click on a play/paused button.\n- **navigate** - Triggered when carousel navigates to a new slide\n\n### **Slots:**\n - **default** - Defines the content of the component.",
588
588
  "doc-url": "",
589
589
  "attributes": [
590
590
  {
@@ -592,6 +592,21 @@
592
592
  "description": "Defines the accessible ARIA name of the component.",
593
593
  "value": { "type": "string", "default": "\"\"" }
594
594
  },
595
+ {
596
+ "name": "autoplay",
597
+ "description": "Controls carousel autoplay functionality",
598
+ "value": { "type": "boolean | undefined", "default": "undefined" }
599
+ },
600
+ {
601
+ "name": "autoplay-speed",
602
+ "description": "Defines carousel autoplay speed in milliseconds till next slide",
603
+ "value": { "type": "number", "default": "2000" }
604
+ },
605
+ {
606
+ "name": "cyclic",
607
+ "description": "Defines whether the carousel should loop, i.e show the first page after the last page is reached and vice versa.",
608
+ "value": { "type": "boolean | undefined", "default": "false" }
609
+ },
595
610
  {
596
611
  "name": "items-per-page",
597
612
  "description": "Defines the number of items per page depending on the carousel width.\n\n- 'S' for screens smaller than 600 pixels.\n- 'M' for screens greater than or equal to 600 pixels and smaller than 1024 pixels.\n- 'L' for screens greater than or equal to 1024 pixels and smaller than 1440 pixels.\n- 'XL' for screens greater than or equal to 1440 pixels.\n\nOne item per page is shown by default.",
@@ -618,6 +633,10 @@
618
633
  }
619
634
  ],
620
635
  "events": [
636
+ {
637
+ "name": "autoplay-toggle-click",
638
+ "description": "Fired event when the user click on a play/paused button."
639
+ },
621
640
  {
622
641
  "name": "navigate",
623
642
  "description": "Triggered when carousel navigates to a new slide"
@@ -630,6 +649,21 @@
630
649
  "description": "Defines the accessible ARIA name of the component.",
631
650
  "value": { "type": "string" }
632
651
  },
652
+ {
653
+ "name": "autoplay",
654
+ "description": "Controls carousel autoplay functionality",
655
+ "value": { "type": "boolean | undefined" }
656
+ },
657
+ {
658
+ "name": "autoplay-speed",
659
+ "description": "Defines carousel autoplay speed in milliseconds till next slide",
660
+ "value": { "type": "number" }
661
+ },
662
+ {
663
+ "name": "cyclic",
664
+ "description": "Defines whether the carousel should loop, i.e show the first page after the last page is reached and vice versa.",
665
+ "value": { "type": "boolean | undefined" }
666
+ },
633
667
  {
634
668
  "name": "items-per-page",
635
669
  "description": "Defines the number of items per page depending on the carousel width.\n\n- 'S' for screens smaller than 600 pixels.\n- 'M' for screens greater than or equal to 600 pixels and smaller than 1024 pixels.\n- 'L' for screens greater than or equal to 1024 pixels and smaller than 1440 pixels.\n- 'XL' for screens greater than or equal to 1440 pixels.\n\nOne item per page is shown by default.",
@@ -647,6 +681,10 @@
647
681
  }
648
682
  ],
649
683
  "events": [
684
+ {
685
+ "name": "autoplay-toggle-click",
686
+ "description": "Fired event when the user click on a play/paused button."
687
+ },
650
688
  {
651
689
  "name": "navigate",
652
690
  "description": "Triggered when carousel navigates to a new slide"
@@ -4885,6 +4923,11 @@
4885
4923
  "description": "Defines a title for sub menu items",
4886
4924
  "value": { "type": "string", "default": "\"\"" }
4887
4925
  },
4926
+ {
4927
+ "name": "number-badge",
4928
+ "description": "Defines the number badge for item",
4929
+ "value": { "type": "string | undefined", "default": "undefined" }
4930
+ },
4888
4931
  {
4889
4932
  "name": "selected",
4890
4933
  "description": "Defines the selected item.",
@@ -4976,6 +5019,11 @@
4976
5019
  "description": "Defines a title for sub menu items",
4977
5020
  "value": { "type": "string" }
4978
5021
  },
5022
+ {
5023
+ "name": "number-badge",
5024
+ "description": "Defines the number badge for item",
5025
+ "value": { "type": "string | undefined" }
5026
+ },
4979
5027
  {
4980
5028
  "name": "selected",
4981
5029
  "description": "Defines the selected item.",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sapudex/web-components",
4
- "version": "2.46.0",
4
+ "version": "2.48.0",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
7
7
  },
package/src/Carousel.ts CHANGED
@@ -10,12 +10,16 @@ import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
10
10
  import {
11
11
  isUp, isDown, isRight, isLeft,
12
12
  } from "@ui5/webcomponents-base/dist/Keys.js";
13
- import { CAROUSEL_NEXT_ARROW_TEXT, CAROUSEL_PREVIOUS_ARROW_TEXT } from "./generated/i18n/i18n-defaults.js";
13
+ import {
14
+ CAROUSEL_NEXT_ARROW_TEXT,
15
+ CAROUSEL_PREVIOUS_ARROW_TEXT,
16
+ CAROUSEL_AUTOPLAY_TOGGLE_START,
17
+ CAROUSEL_AUTOPLAY_TOGGLE_STOP,
18
+ } from "./generated/i18n/i18n-defaults.js";
14
19
  import redirectAttributes from "./utils/redirectAttributes.js";
15
20
  import type UI5Carousel from "@ui5/webcomponents/dist/Carousel.js";
16
21
  import type { CarouselNavigateEventDetail } from "@ui5/webcomponents/dist/Carousel.js";
17
22
  import type { UI5CustomEvent } from "@ui5/webcomponents-base";
18
- import type Icon from "@ui5/webcomponents/dist/Icon.js";
19
23
  import translate from "./utils/translate.js";
20
24
 
21
25
  import CarouselTemplate from "./CarouselTemplate.js";
@@ -23,7 +27,6 @@ import CarouselTemplate from "./CarouselTemplate.js";
23
27
  // Styles
24
28
  import CarouselCss from "./generated/themes/Carousel.css.js";
25
29
  import type CarouselPageIndicatorType from "@ui5/webcomponents/dist/types/CarouselPageIndicatorType.js";
26
- import type UDExButton from "./Button.js";
27
30
 
28
31
  export enum UDExCarouselNavigationPosition {
29
32
  top = "top",
@@ -35,6 +38,10 @@ export enum UDExCarouselButtonDesign {
35
38
  Tertiary = "Tertiary",
36
39
  }
37
40
 
41
+ type UDExCarouselAutoplayToggleEventDetails = {
42
+ isPaused: boolean;
43
+ }
44
+
38
45
  /**
39
46
  * @class
40
47
  *
@@ -65,10 +72,18 @@ export enum UDExCarouselButtonDesign {
65
72
  * @param { CustomEvent }
66
73
  */
67
74
  @event("navigate")
75
+ /**
76
+ * Fired event when the user click on a play/paused button.
77
+ *
78
+ * @public
79
+ * @param {boolean} isPaused - Indicates current state of autoplay
80
+ */
81
+ @event("autoplay-toggle-click", { bubbles: true })
68
82
 
69
83
  class UDExCarousel extends UI5Element {
70
84
  eventDetails!: {
71
85
  "navigate": CarouselNavigateEventDetail,
86
+ "autoplay-toggle-click": UDExCarouselAutoplayToggleEventDetails,
72
87
  };
73
88
  /**
74
89
  * Defines the position of the navigation.
@@ -83,6 +98,37 @@ class UDExCarousel extends UI5Element {
83
98
  */
84
99
  @property()
85
100
  navigationPlacement: `${UDExCarouselNavigationPosition}` = UDExCarouselNavigationPosition.top;
101
+ /**
102
+ * Controls carousel autoplay functionality
103
+ * @public
104
+ * @default undefined
105
+ */
106
+ @property({ type: Boolean })
107
+ autoplay?: boolean;
108
+
109
+ /**
110
+ * Defines carousel autoplay speed in milliseconds till next slide
111
+ * @public
112
+ */
113
+ @property({ type: Number })
114
+ autoplaySpeed: number = 2000;
115
+
116
+ /**
117
+ * Indicates current state of autoplay.
118
+ *
119
+ * @default true
120
+ * @private
121
+ */
122
+ @property({ type: Boolean })
123
+ _autoplayIsPaused = true;
124
+
125
+ /**
126
+ * Defines whether the carousel should loop, i.e show the first page after the last page is reached and vice versa.
127
+ * @public
128
+ * @default false
129
+ */
130
+ @property({ type: Boolean })
131
+ cyclic?: boolean;
86
132
 
87
133
  /**
88
134
  * Defines the content of the component.
@@ -151,6 +197,31 @@ class UDExCarousel extends UI5Element {
151
197
  @i18n("@sapudex/web-components")
152
198
  static i18nBundle: I18nBundle;
153
199
 
200
+ _autoplayInterval: ReturnType<typeof setInterval> | null = null;
201
+ _autoplayLastToggle = Date.now();
202
+ _autoplayMinTimeBetweenToggle = 250;
203
+ _autoplayManualStop = false;
204
+ _autoplayLoop = () => {
205
+ const items = this._carousel?.items;
206
+ if (!items) { return; }
207
+
208
+ const currentSlide = this._carousel._currentPageIndex;
209
+ const itemsPerPage = this._carousel.effectiveItemsPerPage;
210
+ const isLastSlide = currentSlide === (items.length - itemsPerPage);
211
+
212
+ if (isLastSlide && !this.cyclic) {
213
+ this._stopAutoplay();
214
+ this._autoplayManualStop = true;
215
+
216
+ return;
217
+ }
218
+
219
+ const nextSlide = isLastSlide ? 0 : (currentSlide + itemsPerPage);
220
+
221
+ this._carousel?.navigateTo(nextSlide);
222
+ this._calculateDisabledButtonsState();
223
+ };
224
+
154
225
  get nextPageText(): string {
155
226
  return translate(UDExCarousel, CAROUSEL_NEXT_ARROW_TEXT);
156
227
  }
@@ -165,6 +236,26 @@ class UDExCarousel extends UI5Element {
165
236
  return `${classes} udex-carousel__navigation--${this.navigationPlacement}`;
166
237
  }
167
238
 
239
+ get navigationWrapperClass(): string {
240
+ let _class = "udex-carousel__navigation-wrapper";
241
+
242
+ if (this.autoplay) {
243
+ _class += " udex-carousel__navigation-wrapper--autoplay";
244
+ }
245
+
246
+ return _class;
247
+ }
248
+
249
+ get navigationButtonWrapperClass(): string {
250
+ let _class = "udex-carousel__navigation-button-wrapper";
251
+
252
+ if (this._carousel?.isPageTypeDots) {
253
+ _class += " udex-carousel__navigation-button-wrapper--dot-indicators";
254
+ }
255
+
256
+ return _class;
257
+ }
258
+
168
259
  get buttonDesign(): UDExCarouselButtonDesign {
169
260
  return this.navigationPlacement === UDExCarouselNavigationPosition.top
170
261
  ? UDExCarouselButtonDesign.Secondary
@@ -190,25 +281,98 @@ class UDExCarousel extends UI5Element {
190
281
  return this._carousel?.shadowRoot?.querySelector(".ui5-carousel-root");
191
282
  }
192
283
 
284
+ _startAutoplay(): void {
285
+ if (!this.autoplay) { return; }
286
+
287
+ if (!this._carousel?.items) {
288
+ console.warn("[UDExCarousel] Cannot start autoplay on an empty carousel");
289
+ return;
290
+ }
291
+
292
+ const toggleBuffer = Date.now() - this._autoplayLastToggle;
293
+ if (this._autoplayInterval !== null && toggleBuffer <= this._autoplayMinTimeBetweenToggle) {
294
+ this._autoplayLastToggle = Date.now();
295
+ return;
296
+ }
297
+
298
+ if (this._autoplayInterval !== null) {
299
+ clearInterval(this._autoplayInterval);
300
+ }
301
+
302
+ this._autoplayInterval = setInterval(this._autoplayLoop, this.autoplaySpeed);
303
+ this._autoplayIsPaused = false;
304
+ this._autoplayLastToggle = Date.now();
305
+ }
306
+
307
+ _stopAutoplay(): void {
308
+ if (!this._autoplayInterval) { return; }
309
+
310
+ clearInterval(this._autoplayInterval);
311
+ this._autoplayIsPaused = true;
312
+ this._autoplayLastToggle = Date.now();
313
+ }
314
+
315
+ _onAutoplayToggleClick(): void {
316
+ if (this._autoplayIsPaused) {
317
+ this._startAutoplay();
318
+ this._autoplayManualStop = false;
319
+ } else {
320
+ this._stopAutoplay();
321
+ this._autoplayManualStop = true;
322
+ }
323
+
324
+ this.fireDecoratorEvent("autoplay-toggle-click", {
325
+ isPaused: this._autoplayIsPaused,
326
+ });
327
+ }
328
+
329
+ get _isBottomNavigation(): boolean {
330
+ return this.navigationPlacement === UDExCarouselNavigationPosition.bottom;
331
+ }
332
+
333
+ get autoplayToggleButtonTooltipText(): string {
334
+ return this._autoplayIsPaused
335
+ ? translate(UDExCarousel, CAROUSEL_AUTOPLAY_TOGGLE_START)
336
+ : translate(UDExCarousel, CAROUSEL_AUTOPLAY_TOGGLE_STOP);
337
+ }
338
+
339
+ _onFocusIn(): void {
340
+ this._stopAutoplay();
341
+ }
342
+
343
+ _onFocusOut(): void {
344
+ if (!this._autoplayManualStop) { this._startAutoplay(); }
345
+ }
346
+
347
+ _onMouseEnter(): void {
348
+ this._stopAutoplay();
349
+ }
350
+
351
+ _onMouseLeave(): void {
352
+ if (!this._autoplayManualStop) { this._startAutoplay(); }
353
+ }
354
+
193
355
  _calculateDisabledButtonsState() {
194
356
  this.isPrevButtonDisabled = !this._carousel?.hasPrev;
195
357
  this.isNextButtonDisabled = !this._carousel?.hasNext;
196
358
  }
197
359
 
198
- _prevButtonClick(e: UI5CustomEvent<UDExButton, "click">) {
199
- if (this.isPrevButtonDisabled) {
360
+ _prevButtonClick() {
361
+ if (this.isPrevButtonDisabled || !this._carousel) {
200
362
  return;
201
363
  }
202
364
 
203
- this._carousel?._navButtonClick(e as unknown as UI5CustomEvent<Icon, "click">);
365
+ this._carousel.navigateLeft();
366
+ this._calculateDisabledButtonsState();
204
367
  }
205
368
 
206
- _nextButtonClick(e: UI5CustomEvent<UDExButton, "click">) {
207
- if (this.isNextButtonDisabled) {
369
+ _nextButtonClick() {
370
+ if (this.isNextButtonDisabled || !this._carousel) {
208
371
  return;
209
372
  }
210
373
 
211
- this._carousel?._navButtonClick(e as unknown as UI5CustomEvent<Icon, "click">);
374
+ this._carousel.navigateRight();
375
+ this._calculateDisabledButtonsState();
212
376
  }
213
377
 
214
378
  _onkeydown(e: KeyboardEvent) {
@@ -227,9 +391,16 @@ class UDExCarousel extends UI5Element {
227
391
  redirectAttributes(this, "carousel");
228
392
 
229
393
  this._calculateDisabledButtonsState();
394
+
395
+ if (this._autoplayInterval === null) { this._startAutoplay(); }
396
+ }
397
+
398
+ onExitDOM(): void {
399
+ if (this._autoplayInterval) { clearInterval(this._autoplayInterval); }
230
400
  }
231
401
  }
232
402
 
233
403
  UDExCarousel.define();
234
404
 
235
405
  export default UDExCarousel;
406
+ export type { CarouselNavigateEventDetail, UDExCarouselAutoplayToggleEventDetails };
@@ -2,15 +2,19 @@ import type Carousel from "./Carousel.js";
2
2
  import UI5Carousel from "@ui5/webcomponents/dist/Carousel.js";
3
3
  import UDExButton from "./Button.js";
4
4
  import UDExButtonSize from "./types/ButtonSize.js";
5
+ import UDExButtonDesign from "./types/ButtonDesign.js";
5
6
  import type SlottedChild from "@ui5/webcomponents-base/dist/UI5Element.js";
6
7
  import CarouselArrowsPlacement from "@ui5/webcomponents/dist/types/CarouselArrowsPlacement.js";
7
8
  import slimArrowLeft from "@ui5/webcomponents-icons/dist/slim-arrow-left.js";
8
9
  import slimArrowRight from "@ui5/webcomponents-icons/dist/slim-arrow-right.js";
10
+ import play from "@ui5/webcomponents-icons/dist/play.js";
11
+ import pause from "@ui5/webcomponents-icons/dist/pause.js";
9
12
 
10
13
  export default function CarouselTemplate(this: Carousel) {
11
14
  return (
12
15
  <div className={this.carouselClass} onKeyDown={this._onkeydown}>
13
16
  {this.showNavigationButtons.top && navigation.call(this)}
17
+
14
18
  <UI5Carousel
15
19
  itemsPerPage={this.itemsPerPage}
16
20
  pageIndicatorType={this.pageIndicatorType}
@@ -19,11 +23,20 @@ export default function CarouselTemplate(this: Carousel) {
19
23
  arrowsPlacement={CarouselArrowsPlacement.Navigation}
20
24
  accessibleName={this.accessibleName}
21
25
  hidePageIndicator={this._hidePageIndicator}
22
- onNavigate={this._handleNavigate}>
23
- {this.items.map(item =>
24
- <slot name={(item as SlottedChild)._individualSlot}></slot>
25
- )}
26
+ onNavigate={this._handleNavigate}
27
+ onMouseEnter={this._onMouseEnter}
28
+ onMouseLeave={this._onMouseLeave}
29
+ onFocusIn={this._onFocusIn}
30
+ onFocusOut={this._onFocusOut}
31
+ cyclic={this.cyclic}
32
+ >
33
+ {
34
+ this.items.map(item =>
35
+ <slot name={(item as SlottedChild)._individualSlot}></slot>
36
+ )
37
+ }
26
38
  </UI5Carousel>
39
+
27
40
  {this.showNavigationButtons.bottom && navigation.call(this)}
28
41
  </div>
29
42
  );
@@ -31,31 +44,57 @@ export default function CarouselTemplate(this: Carousel) {
31
44
 
32
45
  function navigation(this: Carousel) {
33
46
  const btnClassName = "udex-carousel__navigation-button";
47
+ const icon = this._autoplayIsPaused ? play : pause;
34
48
 
35
49
  return (
36
- <div class="udex-carousel__navigation-wrapper" part="navigation">
37
- <UDExButton
38
- data-ui5-arrow-back
39
- size={UDExButtonSize.Large}
40
- disabled={this.isPrevButtonDisabled}
41
- class={btnClassName}
42
- icon={slimArrowLeft}
43
- design={this.buttonDesign}
44
- tooltip={this.previousPageText}
45
- onClick={this._prevButtonClick}
46
- part="prev-button">
47
- </UDExButton>
48
- <UDExButton
49
- data-ui5-arrow-forward
50
- size={UDExButtonSize.Large}
51
- disabled={this.isNextButtonDisabled}
52
- class={btnClassName}
53
- icon={slimArrowRight}
54
- design={this.buttonDesign}
55
- tooltip={this.nextPageText}
56
- onClick={this._nextButtonClick}
57
- part="next-button">
58
- </UDExButton>
50
+ <div className={this.navigationWrapperClass} part="navigation">
51
+ {
52
+ this.autoplay &&
53
+ <UDExButton
54
+ class={`udex-carousel__autoplay-toggle-button`}
55
+ size={UDExButtonSize.Large}
56
+ design={UDExButtonDesign.Tertiary}
57
+ icon={icon}
58
+ onClick={this._onAutoplayToggleClick}
59
+ tooltip={this.autoplayToggleButtonTooltipText}
60
+ ></UDExButton>
61
+ }
62
+
63
+ <div className={this.navigationButtonWrapperClass}>
64
+ <UDExButton
65
+ data-ui5-arrow-back
66
+ size={UDExButtonSize.Large}
67
+ disabled={this.isPrevButtonDisabled}
68
+ class={btnClassName}
69
+ icon={slimArrowLeft}
70
+ design={this.buttonDesign}
71
+ tooltip={this.previousPageText}
72
+ onClick={this._prevButtonClick}
73
+ part="prev-button">
74
+ </UDExButton>
75
+
76
+ {
77
+ this._isBottomNavigation &&
78
+ <div className="udex-carousel__navigation-page-indicator-spacer" />
79
+ }
80
+
81
+ <UDExButton
82
+ data-ui5-arrow-forward
83
+ size={UDExButtonSize.Large}
84
+ disabled={this.isNextButtonDisabled}
85
+ class={btnClassName}
86
+ icon={slimArrowRight}
87
+ design={this.buttonDesign}
88
+ tooltip={this.nextPageText}
89
+ onClick={this._nextButtonClick}
90
+ part="next-button">
91
+ </UDExButton>
92
+ </div>
93
+
94
+ {
95
+ this.autoplay && this._isBottomNavigation &&
96
+ <div className="udex-carousel__navigation-spacer"></div>
97
+ }
59
98
  </div>
60
99
  );
61
100
  }
package/src/DatePicker.ts CHANGED
@@ -215,6 +215,13 @@ class UDExDatePicker extends DateComponentBase {
215
215
  @property()
216
216
  _tempValue!: string;
217
217
 
218
+ /**
219
+ * Tracks whether the calendar popover is currently open, used to reflect aria-expanded on the control button.
220
+ * @private
221
+ */
222
+ @property({ type: Boolean, noAttribute: true })
223
+ _isPopoverOpen: boolean = false;
224
+
218
225
  @i18n("@sapudex/web-components")
219
226
  static i18nBundle: I18nBundle;
220
227
 
@@ -237,6 +244,7 @@ class UDExDatePicker extends DateComponentBase {
237
244
  }
238
245
 
239
246
  _afterDropdownClose(): void {
247
+ this._isPopoverOpen = false;
240
248
  this._dropdownTrigger.active = false;
241
249
  this._dropdownTrigger.iconActive = false;
242
250
  this._dropdownTrigger.shadowRoot?.querySelector("input")?.blur();
@@ -244,6 +252,7 @@ class UDExDatePicker extends DateComponentBase {
244
252
  }
245
253
 
246
254
  _afterDropdownOpen(): void {
255
+ this._isPopoverOpen = true;
247
256
  this._dropdownTrigger.iconActive = true;
248
257
  }
249
258
 
@@ -7,7 +7,6 @@ export default function DatePickerTemplate(this: DatePicker) {
7
7
  <>
8
8
  <UDExTextField
9
9
  class="udex-date-picker__input"
10
- _aria-has-popup="grid"
11
10
  icon="appointment-2"
12
11
  value={this.value}
13
12
  placeholder={this._effectivePlaceholder}
@@ -15,6 +14,8 @@ export default function DatePickerTemplate(this: DatePicker) {
15
14
  accessible-name={this.dateAccessibleName}
16
15
  accessible-name-ref={this.accessibleNameRef}
17
16
  accessible-icon-name={this.accessibleIconName}
17
+ _icon-aria-has-popup="grid"
18
+ _icon-aria-expanded={this._isPopoverOpen ? "true" : "false"}
18
19
  {...(this.disabled ? { "disabled": true } : {})}
19
20
  {...(this.required ? { "required": true } : {})}
20
21
  {...(this.readonly ? { "readonly": true } : {})}
@@ -12,6 +12,7 @@
12
12
  @mousedown="{{handleMouseDown}}"
13
13
  @mouseup="{{handleMouseUp}}">
14
14
  {{> content}}
15
+ {{> badge}}
15
16
  </a>
16
17
  {{#if isTargetBlank}}
17
18
  <span
@@ -35,6 +36,7 @@
35
36
  @mousedown="{{handleMouseDown}}"
36
37
  @mouseup="{{handleMouseUp}}">
37
38
  {{> content}}
39
+ {{> badge}}
38
40
  </button>
39
41
  {{> dropdown}}
40
42
  {{else}}
@@ -52,6 +54,7 @@
52
54
  @mouseup="{{handleMouseUp}}"
53
55
  @click="{{handleItemClick}}">
54
56
  {{> content}}
57
+ {{> badge}}
55
58
  </button>
56
59
  {{> dropdown}}
57
60
  {{/if}}
@@ -119,3 +122,15 @@
119
122
  <div id="{{this._id}}_dropdown"></div>
120
123
  {{/if}}
121
124
  {{/inline}}
125
+
126
+ {{#*inline "badge"}}
127
+ {{#if this.numberBadge}}
128
+ <udex-badge
129
+ class="udex-masthead-item__badge"
130
+ type="Number"
131
+ number-design="Red"
132
+ size="Small">
133
+ {{this.numberBadge}}
134
+ </udex-badge>
135
+ {{/if}}
136
+ {{/inline}}
@@ -283,6 +283,15 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
283
283
  @property({ type: String })
284
284
  label!: string;
285
285
 
286
+ /**
287
+ * Defines the number badge for item
288
+ *
289
+ * @default undefined
290
+ * @public
291
+ */
292
+ @property({ type: String })
293
+ numberBadge?: string;
294
+
286
295
  /**
287
296
  * Slot for the dropdown
288
297
  *
@@ -402,9 +411,9 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
402
411
 
403
412
  handleFocusOutForDropdowns(e: FocusEvent): void {
404
413
  const relatedTarget = e.relatedTarget as HTMLElement;
405
- const target = e.target as HTMLElement;
414
+ const currentItem = relatedTarget.closest("[udex-masthead-item]");
406
415
 
407
- if (this.shouldCloseDropdown(relatedTarget, target)) {
416
+ if (currentItem !== this) {
408
417
  this.closeDropdown();
409
418
  }
410
419
  }
@@ -584,24 +593,6 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
584
593
  return this.isMobile || e.relatedTarget === null || this._preventFocusOut;
585
594
  }
586
595
 
587
- private isProfileButtonTarget(relatedTarget: HTMLElement | null): boolean {
588
- return (relatedTarget?.tagName === "UDEX-AVATAR" || relatedTarget?.tagName === "UDEX-MASTHEAD-ITEM") && this.isProfileBtn;
589
- }
590
-
591
- private isNavItemTarget(target: HTMLElement): boolean {
592
- return target.getAttribute("slot") === "dropdown" && !this.isProfileBtn;
593
- }
594
-
595
- private isRelatedTargetOutside(relatedTarget: HTMLElement | null): boolean {
596
- return relatedTarget?.closest("[udex-masthead-item]") === null;
597
- }
598
-
599
- private shouldCloseDropdown(relatedTarget: HTMLElement, target:HTMLElement): boolean {
600
- return this.isRelatedTargetOutside(relatedTarget)
601
- || this.isProfileButtonTarget(relatedTarget)
602
- || this.isNavItemTarget(target);
603
- }
604
-
605
596
  get dropdownHolder(): HTMLElement {
606
597
  return this.getDomElement(".udex-masthead-item__dropdown")!;
607
598
  }
@@ -611,7 +602,7 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
611
602
  }
612
603
 
613
604
  get additionalClass(): string {
614
- const iconClass = (this.icon || this.image) ? "udex-masthead-item__button--icon" : "";
605
+ const iconClass = (this.icon || this.image || this.isProfileBtn) ? "udex-masthead-item__button--icon" : "";
615
606
  const profileClass = this.isProfileBtn ? "udex-masthead-item__button--profile" : "";
616
607
  const exploreClass = this.isExploreBtn ? "udex-masthead-item__button--explore" : "";
617
608
  const supportClass = this.isSupportBtn ? "udex-masthead-item__button--support" : "";
package/src/Tag.ts CHANGED
@@ -293,10 +293,11 @@ class UDExTag extends UI5Element {
293
293
  const hasIconClass = this.hasIcon ? "udex-tag--has-icon" : "";
294
294
  const readOnlyClass = this.readOnly ? "udex-tag--readonly" : "";
295
295
  const nonSelectableClass = this.nonSelectable && !this.href && !this.nonInteractive ? "udex-tag--nonselectable" : "";
296
+ const nonInteractiveClass = this.nonInteractive ? "udex-tag--noninteractive" : "";
296
297
  const linkTagClass = this.href ? "udex-tag--link" : "";
297
298
  const selectableClass = this.selected ? "udex-tag--selected" : "";
298
299
  const designClass = `udex-tag-${this.design?.toLowerCase()}`;
299
- return `udex-tag udex-tag--${this.size.toLocaleLowerCase()} ${designClass} ${hasIconClass} ${readOnlyClass} ${nonSelectableClass} ${linkTagClass} ${selectableClass}`.trim();
300
+ return `udex-tag udex-tag--${this.size.toLocaleLowerCase()} ${designClass} ${hasIconClass} ${readOnlyClass} ${nonSelectableClass} ${nonInteractiveClass} ${linkTagClass} ${selectableClass}`.trim();
300
301
  }
301
302
 
302
303
  get startIcon(): boolean {
@@ -331,7 +332,7 @@ class UDExTag extends UI5Element {
331
332
  }
332
333
 
333
334
  get hasIcon(): boolean {
334
- return !!this.icon && !this.readOnly;
335
+ return !!this.icon;
335
336
  }
336
337
 
337
338
  get iconAccessibleName(): string {