@sapudex/web-components 2.18.0 → 2.20.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.
- package/bundle.esm.js +3 -0
- package/cypress/specs/AccordionItem.cy.tsx +6 -2
- package/cypress/specs/BusyIndicator.cy.tsx +10 -0
- package/cypress/specs/FilterMenu.cy.tsx +1 -1
- package/cypress/specs/Footer.cy.tsx +9 -2
- package/cypress/specs/ImageGridTicker.cy.tsx +208 -0
- package/cypress/specs/ImageGridTickerItem.cy.tsx +74 -0
- package/cypress/specs/Table.cy.tsx +1 -1
- package/cypress/support/component-imports.instrumented.ts +52 -46
- package/cypress/support/component-imports.src.ts +53 -47
- package/dist/Accordion.d.ts +1 -0
- package/dist/Accordion.js +7 -1
- package/dist/Accordion.js.map +1 -1
- package/dist/AccordionItem.d.ts +8 -0
- package/dist/AccordionItem.js +11 -0
- package/dist/AccordionItem.js.map +1 -1
- package/dist/AccordionItemTemplate.js +2 -2
- package/dist/AccordionItemTemplate.js.map +1 -1
- package/dist/AccordionTemplate.js +2 -2
- package/dist/AccordionTemplate.js.map +1 -1
- package/dist/AssetsVariables.js +6 -0
- package/dist/AssetsVariables.js.map +1 -1
- package/dist/BusyIndicator.d.ts +22 -0
- package/dist/BusyIndicator.js +39 -0
- package/dist/BusyIndicator.js.map +1 -0
- package/dist/FilterMenu.js +2 -2
- package/dist/FilterMenu.js.map +1 -1
- package/dist/Footer.d.ts +10 -0
- package/dist/Footer.js +7 -0
- package/dist/Footer.js.map +1 -1
- package/dist/FooterTemplate.js +3 -3
- package/dist/FooterTemplate.js.map +1 -1
- package/dist/ImageGridTicker.d.ts +129 -0
- package/dist/ImageGridTicker.js +305 -0
- package/dist/ImageGridTicker.js.map +1 -0
- package/dist/ImageGridTickerItem.d.ts +50 -0
- package/dist/ImageGridTickerItem.js +61 -0
- package/dist/ImageGridTickerItem.js.map +1 -0
- package/dist/ImageGridTickerItemTemplate.d.ts +2 -0
- package/dist/ImageGridTickerItemTemplate.js +9 -0
- package/dist/ImageGridTickerItemTemplate.js.map +1 -0
- package/dist/ImageGridTickerTemplate.d.ts +2 -0
- package/dist/ImageGridTickerTemplate.js +14 -0
- package/dist/ImageGridTickerTemplate.js.map +1 -0
- package/dist/SelectBox.js +2 -0
- package/dist/SelectBox.js.map +1 -1
- package/dist/Table.js +2 -2
- package/dist/Table.js.map +1 -1
- package/dist/assets/{InputSuggestions-L-9bNSZM.js → InputSuggestions-DOj9B3SE.js} +2 -2
- package/dist/assets/{ListItemStandardExpandableTextTemplate-C2VMJfHu.js → ListItemStandardExpandableTextTemplate-C6q5EhEr.js} +3 -3
- package/dist/assets/{bundle.esm-D4RSd7yl.js → bundle.esm-CmHUshBw.js} +220 -212
- package/dist/assets/messagebundle_en-BhTYnZbC.js +1 -0
- package/dist/assets/parameters-bundle.css-195ykfle.js +2 -0
- package/dist/assets/parameters-bundle.css-2XlTf-8J.js +2 -0
- package/dist/assets/parameters-bundle.css-7-HTnP5E.js +2 -0
- package/dist/assets/parameters-bundle.css-B7OzyC0l.js +2 -0
- package/dist/assets/parameters-bundle.css-BJjePPyo.js +2 -0
- package/dist/assets/parameters-bundle.css-BVsx_KaG.js +2 -0
- package/dist/assets/parameters-bundle.css-BbOftqiJ.js +2 -0
- package/dist/assets/parameters-bundle.css-BpraBfJY.js +2 -0
- package/dist/assets/parameters-bundle.css-Btm09-js.js +2 -0
- package/dist/assets/parameters-bundle.css-BtvY__7H.js +2 -0
- package/dist/assets/parameters-bundle.css-CAs_WpVc.js +2 -0
- package/dist/assets/parameters-bundle.css-Cqg5HiU_.js +2 -0
- package/dist/assets/parameters-bundle.css-DIUy2Etb.js +2 -0
- package/dist/assets/parameters-bundle.css-Dn173v0e.js +2 -0
- package/dist/assets/parameters-bundle.css-QEiUG73s.js +2 -0
- package/dist/assets/parameters-bundle.css-VUmjvCcs.js +2 -0
- package/dist/css/themes/Button.css +1 -1
- package/dist/css/themes/CountrySelector.css +1 -1
- package/dist/css/themes/DatePickerPopover.css +1 -1
- package/dist/css/themes/ImageGridTicker.css +1 -0
- package/dist/css/themes/ImageGridTickerItem.css +1 -0
- package/dist/css/themes/Quote.css +1 -1
- package/dist/css/themes/RatingIndicator.css +1 -1
- package/dist/css/themes/Slider.css +1 -1
- package/dist/custom-elements-internal.json +431 -143
- package/dist/custom-elements.json +386 -128
- package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
- package/dist/generated/i18n/i18n-defaults.d.ts +3 -1
- package/dist/generated/i18n/i18n-defaults.js +3 -1
- package/dist/generated/i18n/i18n-defaults.js.map +1 -1
- package/dist/generated/templates/SearchTemplate.lit.js +1 -1
- package/dist/generated/templates/SearchTemplate.lit.js.map +1 -1
- package/dist/generated/templates/SearchableListBaseTemplate.lit.js +1 -1
- package/dist/generated/templates/SearchableListBaseTemplate.lit.js.map +1 -1
- package/dist/generated/templates/TableTemplate.lit.js +1 -1
- package/dist/generated/templates/TableTemplate.lit.js.map +1 -1
- package/dist/generated/themes/Button.css.d.ts +1 -1
- package/dist/generated/themes/Button.css.js +1 -1
- package/dist/generated/themes/Button.css.js.map +1 -1
- package/dist/generated/themes/CountrySelector.css.d.ts +1 -1
- package/dist/generated/themes/CountrySelector.css.js +1 -1
- package/dist/generated/themes/CountrySelector.css.js.map +1 -1
- package/dist/generated/themes/DatePickerPopover.css.d.ts +1 -1
- package/dist/generated/themes/DatePickerPopover.css.js +1 -1
- package/dist/generated/themes/DatePickerPopover.css.js.map +1 -1
- package/dist/generated/themes/ImageGridTicker.css.d.ts +2 -0
- package/dist/generated/themes/ImageGridTicker.css.js +8 -0
- package/dist/generated/themes/ImageGridTicker.css.js.map +1 -0
- package/dist/generated/themes/ImageGridTickerItem.css.d.ts +2 -0
- package/dist/generated/themes/ImageGridTickerItem.css.js +8 -0
- package/dist/generated/themes/ImageGridTickerItem.css.js.map +1 -0
- package/dist/generated/themes/Quote.css.d.ts +1 -1
- package/dist/generated/themes/Quote.css.js +1 -1
- package/dist/generated/themes/Quote.css.js.map +1 -1
- package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
- package/dist/generated/themes/RatingIndicator.css.js +1 -1
- package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
- package/dist/generated/themes/Slider.css.d.ts +1 -1
- package/dist/generated/themes/Slider.css.js +1 -1
- package/dist/generated/themes/Slider.css.js.map +1 -1
- package/dist/messagebundle.properties +4 -0
- package/dist/messagebundle_en.properties +2 -0
- package/dist/vscode.html-custom-data.json +56 -6
- package/dist/web-types.json +125 -6
- package/package.json +8 -8
- package/src/Accordion.ts +9 -1
- package/src/AccordionItem.ts +10 -0
- package/src/AccordionItemTemplate.tsx +2 -2
- package/src/AccordionTemplate.tsx +3 -2
- package/src/AssetsVariables.ts +6 -0
- package/src/BusyIndicator.ts +33 -0
- package/src/FilterMenu.ts +2 -2
- package/src/Footer.ts +16 -0
- package/src/FooterTemplate.tsx +26 -11
- package/src/ImageGridTicker.ts +355 -0
- package/src/ImageGridTickerItem.ts +81 -0
- package/src/ImageGridTickerItemTemplate.tsx +28 -0
- package/src/ImageGridTickerTemplate.tsx +50 -0
- package/src/Search.hbs +0 -1
- package/src/SearchableListBase.hbs +2 -2
- package/src/SelectBox.ts +2 -0
- package/src/Table.hbs +2 -2
- package/src/Table.ts +2 -2
- package/src/generated/i18n/i18n-defaults.ts +2 -2
- package/src/generated/templates/SearchTemplate.lit.ts +1 -1
- package/src/generated/templates/SearchableListBaseTemplate.lit.ts +1 -1
- package/src/generated/templates/TableTemplate.lit.ts +1 -1
- package/src/generated/themes/Button.css.ts +1 -1
- package/src/generated/themes/CountrySelector.css.ts +1 -1
- package/src/generated/themes/DatePickerPopover.css.ts +1 -1
- package/src/generated/themes/ImageGridTicker.css.ts +9 -0
- package/src/generated/themes/ImageGridTickerItem.css.ts +9 -0
- package/src/generated/themes/Quote.css.ts +1 -1
- package/src/generated/themes/RatingIndicator.css.ts +1 -1
- package/src/generated/themes/Slider.css.ts +1 -1
- package/src/i18n/messagebundle.properties +4 -0
- package/src/i18n/messagebundle_en.properties +2 -0
- package/src/themes/Button.css +1 -0
- package/src/themes/CountrySelector.css +2 -2
- package/src/themes/DatePickerPopover.css +3 -2
- package/src/themes/ImageGridTicker.css +134 -0
- package/src/themes/ImageGridTickerItem.css +52 -0
- package/src/themes/Quote.css +7 -2
- package/dist/assets/messagebundle_en-D6cJIiUq.js +0 -1
- package/dist/assets/parameters-bundle.css-7tmaWxIc.js +0 -2
- package/dist/assets/parameters-bundle.css-BERBdAGd.js +0 -2
- package/dist/assets/parameters-bundle.css-B_2Jldx4.js +0 -2
- package/dist/assets/parameters-bundle.css-BbhFHnRW.js +0 -2
- package/dist/assets/parameters-bundle.css-Bg4Huwh4.js +0 -2
- package/dist/assets/parameters-bundle.css-BwKgmVCr.js +0 -2
- package/dist/assets/parameters-bundle.css-C759-AfS.js +0 -2
- package/dist/assets/parameters-bundle.css-CCDcKh9J.js +0 -2
- package/dist/assets/parameters-bundle.css-COmXsTqR.js +0 -2
- package/dist/assets/parameters-bundle.css-CPZYPVEO.js +0 -2
- package/dist/assets/parameters-bundle.css-C_z8R1zV.js +0 -2
- package/dist/assets/parameters-bundle.css-CuV0KqCS.js +0 -2
- package/dist/assets/parameters-bundle.css-DT8OC7CO.js +0 -2
- package/dist/assets/parameters-bundle.css-Df2zY3XY.js +0 -2
- package/dist/assets/parameters-bundle.css-H0NCnWYS.js +0 -2
- package/dist/assets/parameters-bundle.css-pC6uofhy.js +0 -2
package/src/FilterMenu.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "@ui5/webcomponents-base/dist/Keys.js";
|
|
10
10
|
import PopupAccessibleRole from "@ui5/webcomponents/dist/types/PopupAccessibleRole.js";
|
|
11
11
|
import Popover from "@ui5/webcomponents/dist/Popover.js";
|
|
12
|
-
import
|
|
12
|
+
import UDExBusyIndicator from "./BusyIndicator.js";
|
|
13
13
|
import Icon from "@ui5/webcomponents/dist/Icon.js";
|
|
14
14
|
import UDExList from "./List.js";
|
|
15
15
|
import UDExListItem from "./ListItem.js";
|
|
@@ -79,7 +79,7 @@ type UDExFilterMenuResetClickEventDetail = {
|
|
|
79
79
|
dependencies: [
|
|
80
80
|
Popover,
|
|
81
81
|
Icon,
|
|
82
|
-
|
|
82
|
+
UDExBusyIndicator,
|
|
83
83
|
UDExFilterMenuItem,
|
|
84
84
|
UDExFilterMenuGroupHeader,
|
|
85
85
|
UDExFilterMenuSelectAll,
|
package/src/Footer.ts
CHANGED
|
@@ -3,6 +3,7 @@ import jsxRenderer from "@ui5/webcomponents-base/renderer/JsxRenderer.js";
|
|
|
3
3
|
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
|
|
4
4
|
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
|
5
5
|
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
|
6
|
+
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
|
|
6
7
|
import type { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
|
|
7
8
|
import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
|
|
8
9
|
import { isDesktop } from "@ui5/webcomponents-base/dist/Device.js";
|
|
@@ -49,6 +50,7 @@ export type FooterLink = {
|
|
|
49
50
|
title: string;
|
|
50
51
|
url: string;
|
|
51
52
|
target: UDExTarget;
|
|
53
|
+
role?: string;
|
|
52
54
|
};
|
|
53
55
|
|
|
54
56
|
export type FooterSocialLink = {
|
|
@@ -194,6 +196,16 @@ class UDExFooter extends UI5Element {
|
|
|
194
196
|
"social-media-link-click": UDExFooterDetailedClickEventDetail,
|
|
195
197
|
"accordion-item-click": UDExAccordionItemClickEventDetail,
|
|
196
198
|
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Defines the slot for custom Social Links.
|
|
202
|
+
*
|
|
203
|
+
* @slot content
|
|
204
|
+
* @public
|
|
205
|
+
*/
|
|
206
|
+
@slot({ type: HTMLElement, individualSlots: true })
|
|
207
|
+
customSocialLinks!: Array<UDExSocialMediaButton>;
|
|
208
|
+
|
|
197
209
|
/**
|
|
198
210
|
* Defines the Logo default title
|
|
199
211
|
*
|
|
@@ -574,6 +586,10 @@ class UDExFooter extends UI5Element {
|
|
|
574
586
|
return UDExFooter.i18nBundle.getText(BACK_TO_TOP);
|
|
575
587
|
}
|
|
576
588
|
|
|
589
|
+
get hasSocialLinksSlot(): boolean {
|
|
590
|
+
return !!this.customSocialLinks.length;
|
|
591
|
+
}
|
|
592
|
+
|
|
577
593
|
_onLogoClick(e: MouseEvent): void {
|
|
578
594
|
this.fireFooterBaseEvent(e, "logo-click");
|
|
579
595
|
}
|
package/src/FooterTemplate.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import UDExAccordionItem from "./AccordionItem.js";
|
|
|
16
16
|
import UDExButton from "./Button.js";
|
|
17
17
|
import UDExButtonDesign from "./types/ButtonDesign.js";
|
|
18
18
|
import UDExButtonSize from "./types/ButtonSize.js";
|
|
19
|
+
import type { AriaRole } from "@ui5/webcomponents-base";
|
|
19
20
|
|
|
20
21
|
export default function FooterTemplate(this: Footer) {
|
|
21
22
|
const rootClass = "udex-footer";
|
|
@@ -178,7 +179,7 @@ export default function FooterTemplate(this: Footer) {
|
|
|
178
179
|
<span className={`${rootClass}__copyright-text`}>{this.copyrightText}</span>
|
|
179
180
|
</div>
|
|
180
181
|
|
|
181
|
-
{this.socialLinksArray.length > 0 && (
|
|
182
|
+
{(this.socialLinksArray.length > 0 || this.hasSocialLinksSlot) && (
|
|
182
183
|
<ul className={`${rootClass}__social-container`}>
|
|
183
184
|
{this.socialLinksArray.map((social, index) => (
|
|
184
185
|
<UDExSocialMediaButton
|
|
@@ -193,6 +194,13 @@ export default function FooterTemplate(this: Footer) {
|
|
|
193
194
|
onui5-click={this._onSocialMediaLinkClick}>
|
|
194
195
|
</UDExSocialMediaButton>
|
|
195
196
|
))}
|
|
197
|
+
{this.hasSocialLinksSlot && (
|
|
198
|
+
<>
|
|
199
|
+
{this.customSocialLinks.map(link =>
|
|
200
|
+
<slot name={link._individualSlot}></slot>
|
|
201
|
+
)}
|
|
202
|
+
</>
|
|
203
|
+
)}
|
|
196
204
|
</ul>
|
|
197
205
|
)}
|
|
198
206
|
</div>
|
|
@@ -203,8 +211,7 @@ export default function FooterTemplate(this: Footer) {
|
|
|
203
211
|
onClick={this.onBackToTopClick}
|
|
204
212
|
design={UDExButtonDesign.Tertiary}
|
|
205
213
|
size={UDExButtonSize.Large}
|
|
206
|
-
tooltip={this.backToTopTitle}
|
|
207
|
-
accessibleName={this.backToTopTitle}>
|
|
214
|
+
tooltip={this.backToTopTitle}>
|
|
208
215
|
</UDExButton>
|
|
209
216
|
</footer>
|
|
210
217
|
);
|
|
@@ -224,7 +231,8 @@ function mobileNavigation(this: Footer, rootClass: string) {
|
|
|
224
231
|
aria-describedby={`${rootClass}__quick-links`}
|
|
225
232
|
href={link.url}
|
|
226
233
|
data-id={link.id}
|
|
227
|
-
onClick={this._onQuickLinksClick}
|
|
234
|
+
onClick={this._onQuickLinksClick}
|
|
235
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
228
236
|
{link.title}
|
|
229
237
|
</a>
|
|
230
238
|
</li>
|
|
@@ -248,7 +256,8 @@ function mobileNavigation(this: Footer, rootClass: string) {
|
|
|
248
256
|
aria-describedby={`${rootClass}__footer__trending`}
|
|
249
257
|
href={link.url}
|
|
250
258
|
data-id={link.id}
|
|
251
|
-
onClick={this._onTrendingClick}
|
|
259
|
+
onClick={this._onTrendingClick}
|
|
260
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
252
261
|
{link.title}
|
|
253
262
|
</a>
|
|
254
263
|
</li>
|
|
@@ -272,7 +281,8 @@ function mobileNavigation(this: Footer, rootClass: string) {
|
|
|
272
281
|
aria-describedby={`${rootClass}__about`}
|
|
273
282
|
href={link.url}
|
|
274
283
|
data-id={link.id}
|
|
275
|
-
onClick={this._onAboutSapClick}
|
|
284
|
+
onClick={this._onAboutSapClick}
|
|
285
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
276
286
|
{link.title}
|
|
277
287
|
</a>
|
|
278
288
|
</li>
|
|
@@ -296,7 +306,8 @@ function mobileNavigation(this: Footer, rootClass: string) {
|
|
|
296
306
|
aria-describedby={`${rootClass}__site-information`}
|
|
297
307
|
href={link.url}
|
|
298
308
|
data-id={link.id}
|
|
299
|
-
onClick={this._onSiteInformationClick}
|
|
309
|
+
onClick={this._onSiteInformationClick}
|
|
310
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
300
311
|
{link.title}
|
|
301
312
|
</a>
|
|
302
313
|
</li>
|
|
@@ -329,7 +340,8 @@ function desktopNavigation(this: Footer, rootClass: string) {
|
|
|
329
340
|
aria-describedby={`${rootClass}__quick-links`}
|
|
330
341
|
data-id={link.id}
|
|
331
342
|
href={link.url}
|
|
332
|
-
onClick={this._onQuickLinksClick}
|
|
343
|
+
onClick={this._onQuickLinksClick}
|
|
344
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
333
345
|
{link.title}
|
|
334
346
|
</a>
|
|
335
347
|
</li>
|
|
@@ -352,7 +364,8 @@ function desktopNavigation(this: Footer, rootClass: string) {
|
|
|
352
364
|
aria-describedby={`${rootClass}__footer__trending`}
|
|
353
365
|
data-id={link.id}
|
|
354
366
|
href={link.url}
|
|
355
|
-
onClick={this._onTrendingClick}
|
|
367
|
+
onClick={this._onTrendingClick}
|
|
368
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
356
369
|
{link.title}
|
|
357
370
|
</a>
|
|
358
371
|
</li>
|
|
@@ -375,7 +388,8 @@ function desktopNavigation(this: Footer, rootClass: string) {
|
|
|
375
388
|
aria-describedby={`${rootClass}__about`}
|
|
376
389
|
data-id={link.id}
|
|
377
390
|
href={link.url}
|
|
378
|
-
onClick={this._onAboutSapClick}
|
|
391
|
+
onClick={this._onAboutSapClick}
|
|
392
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
379
393
|
{link.title}
|
|
380
394
|
</a>
|
|
381
395
|
</li>
|
|
@@ -398,7 +412,8 @@ function desktopNavigation(this: Footer, rootClass: string) {
|
|
|
398
412
|
aria-describedby={`${rootClass}__site-information`}
|
|
399
413
|
data-id={link.id}
|
|
400
414
|
href={link.url}
|
|
401
|
-
onClick={this._onSiteInformationClick}
|
|
415
|
+
onClick={this._onSiteInformationClick}
|
|
416
|
+
{...(link.role ? { "role": link.role as AriaRole } : {})}>
|
|
402
417
|
{link.title}
|
|
403
418
|
</a>
|
|
404
419
|
</li>
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
|
|
2
|
+
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
|
|
3
|
+
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
|
4
|
+
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
|
5
|
+
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
|
|
6
|
+
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
|
|
7
|
+
import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js";
|
|
8
|
+
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
|
|
9
|
+
import type { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
|
|
10
|
+
import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
|
|
11
|
+
import { isDesktop } from "@ui5/webcomponents-base/Device.js";
|
|
12
|
+
import { isLeft, isRight } from "@ui5/webcomponents-base/dist/Keys.js";
|
|
13
|
+
import { PAUSE_BUTTON_ACCESSIBLE_NAME, PLAY_BUTTON_ACCESSIBLE_NAME } from "./generated/i18n/i18n-defaults.js";
|
|
14
|
+
import { BreakpointUtils } from "./utils/Breakpoints.js";
|
|
15
|
+
import type UDExImageGridTickerItem from "./ImageGridTickerItem.js";
|
|
16
|
+
import ImageGridTickerItem from "./ImageGridTickerItem.js";
|
|
17
|
+
import ImageGridTickerTemplate from "./ImageGridTickerTemplate.js";
|
|
18
|
+
|
|
19
|
+
// Styles
|
|
20
|
+
import ImageGridTickerCss from "./generated/themes/ImageGridTicker.css.js";
|
|
21
|
+
|
|
22
|
+
export enum UDExImageGridTickerVariable {
|
|
23
|
+
itemGaps = "--udex-image-grid-ticker-item-gaps",
|
|
24
|
+
itemWidth = "--udex-image-grid-ticker-item-width",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type UDExImageGridTickerPlayBtnClickEventDetail = {
|
|
28
|
+
isPaused: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @class
|
|
33
|
+
*
|
|
34
|
+
* <h3 class="comment-api-title">Overview</h3>
|
|
35
|
+
*
|
|
36
|
+
*
|
|
37
|
+
* <h3>Usage</h3>
|
|
38
|
+
*
|
|
39
|
+
* For the <code>udex-image-grid-ticker</code>
|
|
40
|
+
* <h3>ES6 Module Import</h3>
|
|
41
|
+
*
|
|
42
|
+
* <code>import "@sapudex/web-components/dist/ImageGridTicker.js";</code>
|
|
43
|
+
*
|
|
44
|
+
* @constructor
|
|
45
|
+
* @extends UI5Element
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
@customElement({
|
|
49
|
+
tag: "udex-image-grid-ticker",
|
|
50
|
+
renderer: jsxRenderer,
|
|
51
|
+
styles: ImageGridTickerCss,
|
|
52
|
+
template: ImageGridTickerTemplate,
|
|
53
|
+
dependencies: [ImageGridTickerItem],
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Fired event when the user click on a play/paused button.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
@event("play-button-click", { bubbles: true })
|
|
62
|
+
|
|
63
|
+
class UDExImageGridTicker extends UI5Element {
|
|
64
|
+
eventDetails!: {
|
|
65
|
+
"play-button-click": UDExImageGridTickerPlayBtnClickEventDetail;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Slot for image grid ticker items.
|
|
70
|
+
*
|
|
71
|
+
* @slot
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
@slot({ type: HTMLElement, "default": true, individualSlots: true })
|
|
75
|
+
items!: Array<UDExImageGridTickerItem>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Grayscale mode enhances visual harmony and can be used for minimal,
|
|
79
|
+
* professional layouts or to de-emphasize logos.
|
|
80
|
+
*
|
|
81
|
+
* @default false
|
|
82
|
+
* @public
|
|
83
|
+
*/
|
|
84
|
+
@property({ type: Boolean })
|
|
85
|
+
grayscale = false;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Indicates whether the image grid ticker is scrollable.
|
|
89
|
+
*
|
|
90
|
+
* @default false
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
@property({ type: Boolean })
|
|
94
|
+
_isScrollable = false;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Indicates whether the screen size is small.
|
|
98
|
+
*
|
|
99
|
+
* @default false
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
@property({ type: Boolean })
|
|
103
|
+
_isSmallScreen = false;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Indicates whether the animation is paused.
|
|
107
|
+
*
|
|
108
|
+
* @default false
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
@property({ type: Boolean })
|
|
112
|
+
_isPaused = false;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Indicates focus in state.
|
|
116
|
+
*
|
|
117
|
+
* @default false
|
|
118
|
+
* @private
|
|
119
|
+
*/
|
|
120
|
+
@property({ type: Boolean })
|
|
121
|
+
_isFocusIn: boolean = false;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Indicates mobile view.
|
|
125
|
+
*
|
|
126
|
+
* @default false
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
@property({ type: Boolean })
|
|
130
|
+
_isMobileView: boolean = false;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Defines direction of the component.
|
|
134
|
+
*
|
|
135
|
+
* @default undefined
|
|
136
|
+
* @private
|
|
137
|
+
*/
|
|
138
|
+
@property({ type: String })
|
|
139
|
+
_direction!: string;
|
|
140
|
+
|
|
141
|
+
_isPlayBtnClicked: boolean = false;
|
|
142
|
+
_isMouseDown: boolean = false;
|
|
143
|
+
_handleResizeBound: ResizeObserverCallback;
|
|
144
|
+
|
|
145
|
+
@i18n("@sapudex/web-components")
|
|
146
|
+
static i18nBundle: I18nBundle;
|
|
147
|
+
|
|
148
|
+
constructor() {
|
|
149
|
+
super();
|
|
150
|
+
this._isMobileView = !this.isAtLeastBreakpointM;
|
|
151
|
+
this._handleResizeBound = this._handleResize.bind(this);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
onAfterRendering(): void {
|
|
155
|
+
if (this._isMobileView) {
|
|
156
|
+
this._handleMobileView();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this._handleDesktopView();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
onEnterDOM(): void {
|
|
164
|
+
ResizeHandler.register(this, this._handleResizeBound);
|
|
165
|
+
if (isDesktop()) {
|
|
166
|
+
this.setAttribute("desktop", "");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
onExitDOM(): void {
|
|
171
|
+
ResizeHandler.deregister(this, this._handleResizeBound);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
_handleResize(): void {
|
|
175
|
+
this._isMobileView = !this.isAtLeastBreakpointM;
|
|
176
|
+
this._checkScrollable();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
_checkScrollable(): void {
|
|
180
|
+
if (!this.grid || !this.track || this._isMobileView) {
|
|
181
|
+
this._isScrollable = false;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const { width: itemWidth, gaps: itemGaps } = this.itemDimensions;
|
|
186
|
+
const totalItemWidth = itemWidth + itemGaps;
|
|
187
|
+
const totalWidth = this.items.length * totalItemWidth;
|
|
188
|
+
|
|
189
|
+
this._isScrollable = totalWidth > this.grid.offsetWidth;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
_startAnimation(): void {
|
|
193
|
+
if (this._isScrollable && !this._isPlayBtnClicked && !this._isMobileView) {
|
|
194
|
+
this._isPaused = false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
_stopAnimation(): void {
|
|
199
|
+
if (this._isScrollable && !this._isMobileView) {
|
|
200
|
+
this._isPaused = true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
_toggleAnimation(): void {
|
|
205
|
+
this._isPlayBtnClicked = !this._isPlayBtnClicked;
|
|
206
|
+
if (this._isPaused) {
|
|
207
|
+
this._startAnimation();
|
|
208
|
+
} else {
|
|
209
|
+
this._stopAnimation();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
_onFocusIn(): void {
|
|
214
|
+
if (this._isMouseDown || !this._isScrollable) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this._isFocusIn = true;
|
|
219
|
+
this._stopAnimation();
|
|
220
|
+
|
|
221
|
+
const focusedItem = this.trackItems[this.focusedIndex];
|
|
222
|
+
const isLastItem = this.focusedIndex === this.trackItems.length - 1;
|
|
223
|
+
const { right, left } = focusedItem.getBoundingClientRect();
|
|
224
|
+
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
225
|
+
const isPartiallyVisible = right > 0 && left < windowWidth;
|
|
226
|
+
|
|
227
|
+
if (isPartiallyVisible) {
|
|
228
|
+
focusedItem.scrollIntoView({
|
|
229
|
+
behavior: "smooth",
|
|
230
|
+
block: "nearest",
|
|
231
|
+
inline: "center",
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (isLastItem) {
|
|
236
|
+
this._focusLastItem();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
_onFocusOut(): void {
|
|
241
|
+
this._isFocusIn = false;
|
|
242
|
+
this._startAnimation();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
_onKeyDown(e: KeyboardEvent): void {
|
|
246
|
+
if (isLeft(e) || isRight(e)) {
|
|
247
|
+
e.preventDefault();
|
|
248
|
+
const direction = (isLeft(e) && !this.isRtl) || (isRight(e) && this.isRtl) ? -1 : 1;
|
|
249
|
+
const index = this.focusedIndex + direction;
|
|
250
|
+
|
|
251
|
+
if (index >= 0 && index < this.trackItems.length) {
|
|
252
|
+
this._focusItem(this.trackItems[index]);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
_onMouseDown(): void {
|
|
258
|
+
this._isMouseDown = true;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
_onMouseUp(): void {
|
|
262
|
+
this._isMouseDown = false;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
_focusLastItem(): void {
|
|
266
|
+
const lastItem = this.trackItems[this.items.length - 1];
|
|
267
|
+
this._focusItem(lastItem);
|
|
268
|
+
lastItem.scrollIntoView({
|
|
269
|
+
behavior: "smooth",
|
|
270
|
+
block: "nearest",
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
_handleMobileView(): void {
|
|
275
|
+
this._isScrollable = false;
|
|
276
|
+
this._stopAnimation();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
_handleDesktopView(): void {
|
|
280
|
+
this._handleDirection();
|
|
281
|
+
this._checkScrollable();
|
|
282
|
+
if (this._isScrollable && !this._isPaused && !this._isMobileView) {
|
|
283
|
+
this._startAnimation();
|
|
284
|
+
} else {
|
|
285
|
+
this._stopAnimation();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
_focusItem(item: HTMLElement): void {
|
|
290
|
+
const link = item.shadowRoot?.querySelector(".udex-image-grid-ticker-item__link") as HTMLElement;
|
|
291
|
+
link.focus();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
_handleDirection(): void {
|
|
295
|
+
const directionStyles = window.getComputedStyle(this).getPropertyValue("direction");
|
|
296
|
+
this._direction = directionStyles || "ltr";
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
_onPlayButtonClick(): void {
|
|
300
|
+
this._toggleAnimation();
|
|
301
|
+
this._firePlayButtonClickEvent();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
_firePlayButtonClickEvent(): void {
|
|
305
|
+
this.fireDecoratorEvent("play-button-click", {
|
|
306
|
+
isPaused: this._isPaused,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
_getPropertyValues(variable: string): number {
|
|
311
|
+
const itemStyles = window.getComputedStyle(this.items[0]);
|
|
312
|
+
return parseInt(itemStyles.getPropertyValue(variable));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
get itemDimensions(): { width: number; gaps: number } {
|
|
316
|
+
const width = this._getPropertyValues(UDExImageGridTickerVariable.itemWidth);
|
|
317
|
+
const gaps = this._getPropertyValues(UDExImageGridTickerVariable.itemGaps) * 2;
|
|
318
|
+
return { width, gaps };
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
get trackItems(): HTMLElement[] {
|
|
322
|
+
return Array.from(this.track.children) as HTMLElement[];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
get focusedIndex(): number {
|
|
326
|
+
return this.trackItems.findIndex(item => item.matches(":focus"));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
get isAtLeastBreakpointM(): boolean {
|
|
330
|
+
return BreakpointUtils.isAtLeast("M");
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
get track(): HTMLElement {
|
|
334
|
+
return this.shadowRoot?.querySelector(".udex-image-grid-ticker__track") as HTMLElement;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
get grid(): HTMLElement {
|
|
338
|
+
return this.shadowRoot?.querySelector(".udex-image-grid-ticker") as HTMLElement;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
get isRtl(): boolean {
|
|
342
|
+
return this._direction === "rtl";
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
get playBtnTooltipText(): string {
|
|
346
|
+
return this._isPaused
|
|
347
|
+
? UDExImageGridTicker.i18nBundle.getText(PLAY_BUTTON_ACCESSIBLE_NAME)
|
|
348
|
+
: UDExImageGridTicker.i18nBundle.getText(PAUSE_BUTTON_ACCESSIBLE_NAME);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
UDExImageGridTicker.define();
|
|
353
|
+
|
|
354
|
+
export default UDExImageGridTicker;
|
|
355
|
+
export type { UDExImageGridTickerPlayBtnClickEventDetail };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
|
|
2
|
+
import { isDesktop } from "@ui5/webcomponents-base/Device.js";
|
|
3
|
+
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
|
|
4
|
+
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
|
5
|
+
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
|
|
6
|
+
import ImageGridTickerItemTemplate from "./ImageGridTickerItemTemplate.js";
|
|
7
|
+
|
|
8
|
+
// Styles
|
|
9
|
+
import ImageGridTickerItemCss from "./generated/themes/ImageGridTickerItem.css.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @class
|
|
13
|
+
*
|
|
14
|
+
* <h3 class="comment-api-title">Overview</h3>
|
|
15
|
+
*
|
|
16
|
+
*
|
|
17
|
+
* <h3>Usage</h3>
|
|
18
|
+
*
|
|
19
|
+
* For the <code>udex-image-grid-ticker-item</code>
|
|
20
|
+
* <h3>ES6 Module Import</h3>
|
|
21
|
+
*
|
|
22
|
+
* <code>import "@sapudex/web-components/dist/ImageGridTickerItem.js";</code>
|
|
23
|
+
*
|
|
24
|
+
* @constructor
|
|
25
|
+
* @extends UI5Element
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
@customElement({
|
|
29
|
+
tag: "udex-image-grid-ticker-item",
|
|
30
|
+
renderer: jsxRenderer,
|
|
31
|
+
styles: ImageGridTickerItemCss,
|
|
32
|
+
template: ImageGridTickerItemTemplate,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
class UDExImageGridTickerItem extends UI5Element {
|
|
36
|
+
/**
|
|
37
|
+
* Defines the source URL
|
|
38
|
+
*
|
|
39
|
+
* @default ""
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
@property({ type: String })
|
|
43
|
+
src!: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Defines image alt text
|
|
47
|
+
*
|
|
48
|
+
* @default undefined
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
@property({ type: String })
|
|
52
|
+
alt?: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Defines tooltip on hover
|
|
56
|
+
*
|
|
57
|
+
* @default undefined
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
@property({ type: String })
|
|
61
|
+
tooltip?: string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Defines link URL
|
|
65
|
+
*
|
|
66
|
+
* @default undefined
|
|
67
|
+
* @public
|
|
68
|
+
*/
|
|
69
|
+
@property({ type: String })
|
|
70
|
+
href?: string;
|
|
71
|
+
|
|
72
|
+
onEnterDOM(): void {
|
|
73
|
+
if (isDesktop()) {
|
|
74
|
+
this.setAttribute("desktop", "");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
UDExImageGridTickerItem.define();
|
|
80
|
+
|
|
81
|
+
export default UDExImageGridTickerItem;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type ImageGridTickerItem from "./ImageGridTickerItem.js";
|
|
2
|
+
|
|
3
|
+
export default function ImageGridTickerItemTemplate(this: ImageGridTickerItem) {
|
|
4
|
+
const rootClass = "udex-image-grid-ticker-item";
|
|
5
|
+
const img = (
|
|
6
|
+
<img
|
|
7
|
+
class={`${rootClass}__img`}
|
|
8
|
+
part="grid-image"
|
|
9
|
+
src={this.src}
|
|
10
|
+
alt={this.alt}
|
|
11
|
+
title={this.tooltip}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div class={rootClass}>
|
|
17
|
+
{this.href && this.href.length > 0
|
|
18
|
+
? <a
|
|
19
|
+
class={`${rootClass}__link`}
|
|
20
|
+
href={this.href}
|
|
21
|
+
title={this.tooltip}>
|
|
22
|
+
{img}
|
|
23
|
+
</a>
|
|
24
|
+
: img
|
|
25
|
+
}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type ImageGridTicker from "./ImageGridTicker.js";
|
|
2
|
+
import ImageGridTickerItem from "./ImageGridTickerItem.js";
|
|
3
|
+
import UDExButton from "./Button.js";
|
|
4
|
+
import UDExButtonDesign from "./types/ButtonDesign.js";
|
|
5
|
+
import playIcon from "@ui5/webcomponents-icons/dist/play.js";
|
|
6
|
+
import pauseIcon from "@ui5/webcomponents-icons/dist/pause.js";
|
|
7
|
+
|
|
8
|
+
export default function ImageGridTickerTemplate(this: ImageGridTicker) {
|
|
9
|
+
const rootClass = "udex-image-grid-ticker";
|
|
10
|
+
const items = this._isScrollable && !this._isMobileView && !this._isFocusIn ? [...this.items, ...this.items] : this.items;
|
|
11
|
+
const btnIcon = this._isPaused ? playIcon : pauseIcon;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div class={rootClass}>
|
|
15
|
+
{this._isScrollable &&
|
|
16
|
+
<div className={`${rootClass}__play-button-holder`}>
|
|
17
|
+
<UDExButton
|
|
18
|
+
class={`${rootClass}__play-button`}
|
|
19
|
+
icon={btnIcon}
|
|
20
|
+
design={UDExButtonDesign.Invisible}
|
|
21
|
+
onClick={this._onPlayButtonClick}
|
|
22
|
+
tooltip={this.playBtnTooltipText}>
|
|
23
|
+
</UDExButton>
|
|
24
|
+
</div>
|
|
25
|
+
}
|
|
26
|
+
<div className={`${rootClass}__track-holder`}>
|
|
27
|
+
<div className={`${rootClass}__track-wrapper`}>
|
|
28
|
+
<div
|
|
29
|
+
className={`${rootClass}__track`}
|
|
30
|
+
onMouseEnter={this._stopAnimation}
|
|
31
|
+
onMouseLeave={this._startAnimation}
|
|
32
|
+
onFocusIn={this._onFocusIn}
|
|
33
|
+
onFocusOut={this._onFocusOut}
|
|
34
|
+
onKeyDown={this._onKeyDown}
|
|
35
|
+
onMouseDown={this._onMouseDown}
|
|
36
|
+
onMouseUp={this._onMouseUp}>
|
|
37
|
+
{items.map(item =>
|
|
38
|
+
<ImageGridTickerItem
|
|
39
|
+
src={item.src}
|
|
40
|
+
alt={item.alt}
|
|
41
|
+
tooltip={item.tooltip}
|
|
42
|
+
href={item.href}>
|
|
43
|
+
</ImageGridTickerItem>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
}
|