@wlloyalty/wll-react-sdk 1.0.102 → 1.0.104
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/dist/index.d.ts +9 -0
- package/dist/native.js +239 -94
- package/dist/native.js.map +1 -1
- package/dist/types/context/WllSdkContext.d.ts +3 -0
- package/dist/types/mocks/tiles/badgeTile.d.ts +1 -0
- package/dist/types/types/tile.d.ts +1 -0
- package/dist/types/unit-tests/eventEmitter.spec.d.ts +1 -0
- package/dist/types/utils/eventEmitter.d.ts +44 -0
- package/dist/types/utils/transforms.d.ts +13 -0
- package/dist/web.js +215 -64
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -196,6 +196,7 @@ declare class BadgeTileConfig {
|
|
|
196
196
|
emptyBadgeArtworkUrl?: string;
|
|
197
197
|
awardedDatePrefix?: string;
|
|
198
198
|
badgeNotEarnedMessage?: string;
|
|
199
|
+
lastEarnedAt?: string;
|
|
199
200
|
}
|
|
200
201
|
type BadgeDetail = {
|
|
201
202
|
name: string;
|
|
@@ -661,6 +662,12 @@ type NavigationConfig = {
|
|
|
661
662
|
baseUrl?: string;
|
|
662
663
|
};
|
|
663
664
|
|
|
665
|
+
/**
|
|
666
|
+
* Supported event types for the SDK event system
|
|
667
|
+
* @typedef {string} EventTypes
|
|
668
|
+
*/
|
|
669
|
+
type EventTypes = 'GROUP_DATA_CHANGED' | 'SECTION_DATA_CHANGED' | 'TILE_DATA_CHANGED' | string;
|
|
670
|
+
|
|
664
671
|
type Fetcher = <T>(endpoint: string, options?: RequestInit) => Promise<APIResponse<T>>;
|
|
665
672
|
type SDKConfig = {
|
|
666
673
|
apiKey: string;
|
|
@@ -679,6 +686,8 @@ type WllSdkContextType = ThemeContextType & {
|
|
|
679
686
|
getTileByID: (id: string) => Promise<APIResponse<Tile>>;
|
|
680
687
|
handleNavigation: (link: string, target: CTALinkTarget) => Promise<void>;
|
|
681
688
|
refreshGroup: (id: string) => Promise<APIResponse<TGroup>>;
|
|
689
|
+
notifyDataChange: (eventType: EventTypes, data?: any) => void;
|
|
690
|
+
subscribeToDataChange: (eventType: EventTypes, callback: (data?: any) => void) => () => void;
|
|
682
691
|
} & Readonly<{
|
|
683
692
|
readonly config: SDKConfig;
|
|
684
693
|
}>;
|
package/dist/native.js
CHANGED
|
@@ -1595,6 +1595,66 @@ var useGetGroupByID = createResourceGetter('groups', true);
|
|
|
1595
1595
|
var useGetSectionByID = createResourceGetter('sections');
|
|
1596
1596
|
var useGetTileByID = createResourceGetter('tiles');
|
|
1597
1597
|
|
|
1598
|
+
/**
|
|
1599
|
+
* A simple event emitter for handling SDK events
|
|
1600
|
+
* Provides a pub-sub mechanism for components to communicate
|
|
1601
|
+
*/
|
|
1602
|
+
var EventEmitter = /** @class */ (function () {
|
|
1603
|
+
function EventEmitter() {
|
|
1604
|
+
/**
|
|
1605
|
+
* Map of event types to arrays of callback functions
|
|
1606
|
+
* @private
|
|
1607
|
+
*/
|
|
1608
|
+
this.events = new Map();
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Subscribe to an event
|
|
1612
|
+
* @param {EventTypes} event - The event type to subscribe to
|
|
1613
|
+
* @param {EventCallback} callback - The callback function to execute when the event is emitted
|
|
1614
|
+
* @returns {Function} An unsubscribe function that removes this callback when called
|
|
1615
|
+
*/
|
|
1616
|
+
EventEmitter.prototype.on = function (event, callback) {
|
|
1617
|
+
var _this = this;
|
|
1618
|
+
var _a;
|
|
1619
|
+
if (!this.events.has(event)) {
|
|
1620
|
+
this.events.set(event, []);
|
|
1621
|
+
}
|
|
1622
|
+
(_a = this.events.get(event)) === null || _a === void 0 ? void 0 : _a.push(callback);
|
|
1623
|
+
return function () {
|
|
1624
|
+
var callbacks = _this.events.get(event);
|
|
1625
|
+
if (callbacks) {
|
|
1626
|
+
var index = callbacks.indexOf(callback);
|
|
1627
|
+
if (index !== -1) {
|
|
1628
|
+
callbacks.splice(index, 1);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
};
|
|
1633
|
+
/**
|
|
1634
|
+
* Emit an event with optional data
|
|
1635
|
+
* @param {EventTypes} event - The event type to emit
|
|
1636
|
+
* @param {any} [data] - Optional data to pass to the event callbacks
|
|
1637
|
+
*/
|
|
1638
|
+
EventEmitter.prototype.emit = function (event, data) {
|
|
1639
|
+
var callbacks = this.events.get(event);
|
|
1640
|
+
if (callbacks) {
|
|
1641
|
+
callbacks.forEach(function (callback) { return callback(data); });
|
|
1642
|
+
}
|
|
1643
|
+
};
|
|
1644
|
+
/**
|
|
1645
|
+
* Remove all event listeners
|
|
1646
|
+
* Use this method to clean up when the event emitter is no longer needed
|
|
1647
|
+
*/
|
|
1648
|
+
EventEmitter.prototype.clear = function () {
|
|
1649
|
+
this.events.clear();
|
|
1650
|
+
};
|
|
1651
|
+
return EventEmitter;
|
|
1652
|
+
}());
|
|
1653
|
+
/**
|
|
1654
|
+
* Singleton instance of the EventEmitter for use throughout the SDK
|
|
1655
|
+
*/
|
|
1656
|
+
var sdkEventEmitter = new EventEmitter();
|
|
1657
|
+
|
|
1598
1658
|
var sizes = {
|
|
1599
1659
|
borderRadiusSm: 15,
|
|
1600
1660
|
borderRadiusLg: 20,
|
|
@@ -1961,6 +2021,12 @@ var WllSdkProvider = function (_a) {
|
|
|
1961
2021
|
return [2 /*return*/, getGroupByID(id)];
|
|
1962
2022
|
});
|
|
1963
2023
|
}); }, [getGroupByID]);
|
|
2024
|
+
var notifyDataChange = React.useCallback(function (eventType, data) {
|
|
2025
|
+
sdkEventEmitter.emit(eventType, data);
|
|
2026
|
+
}, []);
|
|
2027
|
+
var subscribeToDataChange = React.useCallback(function (eventType, callback) {
|
|
2028
|
+
return sdkEventEmitter.on(eventType, callback);
|
|
2029
|
+
}, []);
|
|
1964
2030
|
var contextValue = React.useMemo(function () { return ({
|
|
1965
2031
|
theme: theme,
|
|
1966
2032
|
setTheme: setTheme,
|
|
@@ -1969,6 +2035,8 @@ var WllSdkProvider = function (_a) {
|
|
|
1969
2035
|
getTileByID: getTileByID,
|
|
1970
2036
|
handleNavigation: handleNavigation,
|
|
1971
2037
|
refreshGroup: refreshGroup,
|
|
2038
|
+
notifyDataChange: notifyDataChange,
|
|
2039
|
+
subscribeToDataChange: subscribeToDataChange,
|
|
1972
2040
|
config: config,
|
|
1973
2041
|
}); }, [
|
|
1974
2042
|
theme,
|
|
@@ -1978,6 +2046,8 @@ var WllSdkProvider = function (_a) {
|
|
|
1978
2046
|
getTileByID,
|
|
1979
2047
|
handleNavigation,
|
|
1980
2048
|
refreshGroup,
|
|
2049
|
+
notifyDataChange,
|
|
2050
|
+
subscribeToDataChange,
|
|
1981
2051
|
config,
|
|
1982
2052
|
]);
|
|
1983
2053
|
return (jsxRuntimeExports.jsx(WllSdkContext.Provider, { value: contextValue, children: jsxRuntimeExports.jsx(ResponsiveProvider, { children: children }) }));
|
|
@@ -2579,7 +2649,7 @@ var BaseTileBody = function (props) {
|
|
|
2579
2649
|
return undefined;
|
|
2580
2650
|
return isDesktop ? 3 : isTablet ? 4 : 3;
|
|
2581
2651
|
};
|
|
2582
|
-
return (jsxRuntimeExports.jsx(Text, __assign({ variant: "body" }, props, {
|
|
2652
|
+
return (jsxRuntimeExports.jsx(Text, __assign({ variant: "body" }, props, { role: "article", accessibilityLabel: body, numberOfLines: getNumberOfLines(), testID: "tile-body", children: body })));
|
|
2583
2653
|
};
|
|
2584
2654
|
|
|
2585
2655
|
/**
|
|
@@ -2691,7 +2761,7 @@ var BaseTileContent = function (_a) {
|
|
|
2691
2761
|
justifyContent: 'center',
|
|
2692
2762
|
height: !artworkUrl ? '100%' : undefined,
|
|
2693
2763
|
},
|
|
2694
|
-
],
|
|
2764
|
+
], role: "none", children: children }));
|
|
2695
2765
|
};
|
|
2696
2766
|
|
|
2697
2767
|
/**
|
|
@@ -2714,7 +2784,7 @@ var BaseTileHeader = function (_a) {
|
|
|
2714
2784
|
return null;
|
|
2715
2785
|
var dynamicStyles = useBaseTileStyles();
|
|
2716
2786
|
var combinedStyle = __assign(__assign(__assign({}, dynamicStyles.header), { marginTop: sizeInfo.isHalfSize ? 0 : dynamicStyles.header.marginTop }), (sizeInfo.isHalfSize ? { alignItems: 'center' } : {}));
|
|
2717
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { style: combinedStyle, testID: "tile-header",
|
|
2787
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { style: combinedStyle, testID: "tile-header", role: "heading", children: children }));
|
|
2718
2788
|
};
|
|
2719
2789
|
|
|
2720
2790
|
/**
|
|
@@ -2731,7 +2801,7 @@ var BaseTileMedia = function (props) {
|
|
|
2731
2801
|
var styles = useBaseTileStyles();
|
|
2732
2802
|
if (!artworkUrl)
|
|
2733
2803
|
return null;
|
|
2734
|
-
return (jsxRuntimeExports.jsx(ProgressiveImage, __assign({}, props, { source: { uri: artworkUrl }, testID: "tile-media", style: [props.style, baseStyles.media, styles.media], alt: "Content image".concat(title ? " for ".concat(title) : ''),
|
|
2804
|
+
return (jsxRuntimeExports.jsx(ProgressiveImage, __assign({}, props, { source: { uri: artworkUrl }, testID: "tile-media", style: [props.style, baseStyles.media, styles.media], alt: "Content image".concat(title ? " for ".concat(title) : ''), role: "img" })));
|
|
2735
2805
|
};
|
|
2736
2806
|
|
|
2737
2807
|
/**
|
|
@@ -2754,7 +2824,7 @@ var BaseTileTitle = function () {
|
|
|
2754
2824
|
// Don't show title for half tiles with image
|
|
2755
2825
|
if ((isHalfSize && artworkUrl) || !title)
|
|
2756
2826
|
return null;
|
|
2757
|
-
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Text, { variant: "title",
|
|
2827
|
+
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Text, { variant: "title", role: "heading", accessibilityLabel: title, numberOfLines: 1, testID: "tile-title", children: title }), ctaLink && (jsxRuntimeExports.jsx(Icon, { name: "ChevronRight", color: (_b = (_a = sdk.theme) === null || _a === void 0 ? void 0 : _a.derivedSurfaceText) === null || _b === void 0 ? void 0 : _b[20], accessibilityLabel: "View details" }))] }));
|
|
2758
2828
|
};
|
|
2759
2829
|
|
|
2760
2830
|
/**
|
|
@@ -2807,7 +2877,7 @@ var BaseTileContainer = function (_a) {
|
|
|
2807
2877
|
layout,
|
|
2808
2878
|
style,
|
|
2809
2879
|
];
|
|
2810
|
-
}, onPress: handlePress, disabled: tile.type !== 'REWARD' && tile.type !== 'REWARD_CATEGORY' && !ctaLink, accessible: true,
|
|
2880
|
+
}, onPress: handlePress, disabled: tile.type !== 'REWARD' && tile.type !== 'REWARD_CATEGORY' && !ctaLink, accessible: true, role: "button", accessibilityLabel: "".concat(title).concat(ctaLink ? ' - Click to open' : ''), accessibilityState: { disabled: !ctaLink }, children: children }));
|
|
2811
2881
|
};
|
|
2812
2882
|
/**
|
|
2813
2883
|
* BaseTileRoot component to provide context and render children.
|
|
@@ -3032,6 +3102,63 @@ function withTileFetching(WrappedComponent) {
|
|
|
3032
3102
|
};
|
|
3033
3103
|
}
|
|
3034
3104
|
|
|
3105
|
+
/**
|
|
3106
|
+
* Sorts tiles by priority (higher priority first) and maintains original order for equal priorities
|
|
3107
|
+
* @param tiles Array of tiles to sort
|
|
3108
|
+
* @returns Sorted array of tiles
|
|
3109
|
+
*/
|
|
3110
|
+
var sortByPriority = function (tiles) {
|
|
3111
|
+
return __spreadArray([], tiles, true).sort(function (a, b) {
|
|
3112
|
+
// Sort by priority (higher priority first)
|
|
3113
|
+
if (a.priority !== b.priority) {
|
|
3114
|
+
return b.priority - a.priority;
|
|
3115
|
+
}
|
|
3116
|
+
// If priorities are equal, maintain original order
|
|
3117
|
+
return tiles.indexOf(a) - tiles.indexOf(b);
|
|
3118
|
+
});
|
|
3119
|
+
};
|
|
3120
|
+
/**
|
|
3121
|
+
* Transforms locale to a locale that is supported by the browser
|
|
3122
|
+
* @param locale Two-letter locale code to transform (en, fr, etc.)
|
|
3123
|
+
* @returns Full locale string (e.g., en-GB, fr-FR)
|
|
3124
|
+
*/
|
|
3125
|
+
var transformLocale = function (locale) {
|
|
3126
|
+
var localeMapping = {
|
|
3127
|
+
en: 'en-GB',
|
|
3128
|
+
fr: 'fr-FR',
|
|
3129
|
+
es: 'es-ES',
|
|
3130
|
+
de: 'de-DE',
|
|
3131
|
+
it: 'it-IT',
|
|
3132
|
+
pt: 'pt-PT',
|
|
3133
|
+
us: 'en-US',
|
|
3134
|
+
};
|
|
3135
|
+
var languageCode = (locale !== null && locale !== void 0 ? locale : 'en').toLowerCase();
|
|
3136
|
+
return localeMapping[languageCode] || 'en-GB';
|
|
3137
|
+
};
|
|
3138
|
+
/**
|
|
3139
|
+
* Formats a date string to a localized date string based on user locale
|
|
3140
|
+
* @param date Date string to format
|
|
3141
|
+
* @param userLocale User's locale (defaults to 'en')
|
|
3142
|
+
* @returns Formatted date string or fallback message
|
|
3143
|
+
*/
|
|
3144
|
+
var handleLastEarnedDate = function (date, userLocale) {
|
|
3145
|
+
if (userLocale === void 0) { userLocale = 'en'; }
|
|
3146
|
+
if (!date)
|
|
3147
|
+
return 'Date not available';
|
|
3148
|
+
try {
|
|
3149
|
+
var formattedLocale = transformLocale(userLocale);
|
|
3150
|
+
var dateObj = new Date(date);
|
|
3151
|
+
if (isNaN(dateObj.getTime())) {
|
|
3152
|
+
return 'Invalid Date';
|
|
3153
|
+
}
|
|
3154
|
+
return dateObj.toLocaleDateString(formattedLocale);
|
|
3155
|
+
}
|
|
3156
|
+
catch (error) {
|
|
3157
|
+
console.error('Error formatting date:', error);
|
|
3158
|
+
return 'Invalid Date';
|
|
3159
|
+
}
|
|
3160
|
+
};
|
|
3161
|
+
|
|
3035
3162
|
/**
|
|
3036
3163
|
* Custom hook that returns the styles for the BadgeTile component.
|
|
3037
3164
|
* Applies responsive styling based on the current device.
|
|
@@ -3095,7 +3222,7 @@ var BadgeTileDateEarned = function () {
|
|
|
3095
3222
|
var theme = useWllSdk().theme;
|
|
3096
3223
|
if (!isContextValid(tileContext))
|
|
3097
3224
|
return null;
|
|
3098
|
-
var _a = tileContext.configuration, count = _a.count, awardedDatePrefix = _a.awardedDatePrefix,
|
|
3225
|
+
var _a = tileContext.configuration, count = _a.count, awardedDatePrefix = _a.awardedDatePrefix, lastEarnedAt = _a.lastEarnedAt, badgeNotEarnedMessage = _a.badgeNotEarnedMessage, type = _a.type, locale = _a.locale;
|
|
3099
3226
|
// Don't show for Latest type with count=0
|
|
3100
3227
|
if (type === exports.BadgeTileType.Latest && count === 0) {
|
|
3101
3228
|
return null;
|
|
@@ -3111,10 +3238,10 @@ var BadgeTileDateEarned = function () {
|
|
|
3111
3238
|
var textColor = getReadableTextColor(backgroundColor);
|
|
3112
3239
|
var displayText = count === 0
|
|
3113
3240
|
? badgeNotEarnedMessage
|
|
3114
|
-
: "".concat(awardedDatePrefix, " ").concat(
|
|
3241
|
+
: "".concat(awardedDatePrefix, " ").concat(handleLastEarnedDate(lastEarnedAt, locale));
|
|
3115
3242
|
var accessibilityLabel = count === 0
|
|
3116
3243
|
? 'Badge not yet earned'
|
|
3117
|
-
: "Badge earned on ".concat(
|
|
3244
|
+
: "Badge earned on ".concat(handleLastEarnedDate(lastEarnedAt, locale));
|
|
3118
3245
|
return (jsxRuntimeExports.jsx(reactNative.View, { style: containerStyle, accessible: true, accessibilityLabel: accessibilityLabel, testID: "badge-tile-date-earned", children: jsxRuntimeExports.jsx(Text, { variant: "label", style: [styles.dateEarnedText, { color: textColor }], numberOfLines: 1, ellipsizeMode: "tail", accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: displayText }) }));
|
|
3119
3246
|
};
|
|
3120
3247
|
|
|
@@ -3296,7 +3423,7 @@ var BannerTileDescription = function () {
|
|
|
3296
3423
|
var description = bannerContext.configuration.description;
|
|
3297
3424
|
if (!description)
|
|
3298
3425
|
return null;
|
|
3299
|
-
return (jsxRuntimeExports.jsx(Text, { style: styles.description,
|
|
3426
|
+
return (jsxRuntimeExports.jsx(Text, { style: styles.description, role: "article", accessibilityLabel: description, testID: "banner-tile-description", children: description }));
|
|
3300
3427
|
};
|
|
3301
3428
|
|
|
3302
3429
|
/**
|
|
@@ -3316,7 +3443,7 @@ var BannerTileMedia = function (_a) {
|
|
|
3316
3443
|
var containerStyle = {
|
|
3317
3444
|
width: isArtworkOnly ? '100%' : '30%',
|
|
3318
3445
|
};
|
|
3319
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.mediaContainer, containerStyle],
|
|
3446
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.mediaContainer, containerStyle], role: "img", accessibilityLabel: "Banner image".concat(title ? " for ".concat(title) : ''), testID: "banner-tile-media", children: jsxRuntimeExports.jsx(ProgressiveImage, { source: { uri: artworkUrl }, style: styles.media, alt: "Banner image".concat(title ? " for ".concat(title) : '') }) }));
|
|
3320
3447
|
};
|
|
3321
3448
|
|
|
3322
3449
|
/**
|
|
@@ -3332,7 +3459,7 @@ var BannerTileTitle = function () {
|
|
|
3332
3459
|
var title = bannerContext.configuration.title;
|
|
3333
3460
|
if (!title)
|
|
3334
3461
|
return null;
|
|
3335
|
-
return (jsxRuntimeExports.jsx(Text, { variant: "title", testID: "banner-tile-title", style: styles.title,
|
|
3462
|
+
return (jsxRuntimeExports.jsx(Text, { variant: "title", testID: "banner-tile-title", style: styles.title, role: "heading", accessibilityLabel: title, children: title }));
|
|
3336
3463
|
};
|
|
3337
3464
|
|
|
3338
3465
|
/**
|
|
@@ -3438,7 +3565,7 @@ var ContentTileMedia = function (_a) {
|
|
|
3438
3565
|
var containerStyle = {
|
|
3439
3566
|
flexBasis: isArtworkOnly ? '100%' : '50%',
|
|
3440
3567
|
};
|
|
3441
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.imageContainer, containerStyle], testID: "content-tile-media",
|
|
3568
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.imageContainer, containerStyle], testID: "content-tile-media", role: "img", accessibilityLabel: "Image for ".concat(title), children: jsxRuntimeExports.jsx(ProgressiveImage, { source: { uri: artworkUrl }, style: styles.image, alt: "Image for ".concat(title) }) }));
|
|
3442
3569
|
};
|
|
3443
3570
|
|
|
3444
3571
|
var ContentTileSummary = function () {
|
|
@@ -3455,7 +3582,7 @@ var ContentTileSummary = function () {
|
|
|
3455
3582
|
var getNumberOfLines = function () {
|
|
3456
3583
|
return isFullSize ? 3 : isHalfSize ? 4 : 3;
|
|
3457
3584
|
};
|
|
3458
|
-
return (jsxRuntimeExports.jsx(Text, { variant: "body",
|
|
3585
|
+
return (jsxRuntimeExports.jsx(Text, { variant: "body", role: "article", accessibilityLabel: body, numberOfLines: getNumberOfLines(), testID: "content-tile-summary", children: body }));
|
|
3459
3586
|
};
|
|
3460
3587
|
|
|
3461
3588
|
var ContentTileTitle = function () {
|
|
@@ -3471,7 +3598,7 @@ var ContentTileTitle = function () {
|
|
|
3471
3598
|
return styles.titleWithLink;
|
|
3472
3599
|
}
|
|
3473
3600
|
};
|
|
3474
|
-
return (jsxRuntimeExports.jsx(Text, { variant: "title",
|
|
3601
|
+
return (jsxRuntimeExports.jsx(Text, { variant: "title", role: "heading", accessibilityLabel: title, numberOfLines: 1, style: handleTitleWidth(), testID: "content-tile-title", children: title }));
|
|
3475
3602
|
};
|
|
3476
3603
|
|
|
3477
3604
|
/**
|
|
@@ -3513,22 +3640,6 @@ var ContentTile = Object.assign(ContentTileRoot, {
|
|
|
3513
3640
|
});
|
|
3514
3641
|
var ContentTile$1 = withTileFetching(ContentTile);
|
|
3515
3642
|
|
|
3516
|
-
/**
|
|
3517
|
-
* Sorts tiles by priority (higher priority first) and maintains original order for equal priorities
|
|
3518
|
-
* @param tiles Array of tiles to sort
|
|
3519
|
-
* @returns Sorted array of tiles
|
|
3520
|
-
*/
|
|
3521
|
-
var sortByPriority = function (tiles) {
|
|
3522
|
-
return __spreadArray([], tiles, true).sort(function (a, b) {
|
|
3523
|
-
// Sort by priority (higher priority first)
|
|
3524
|
-
if (a.priority !== b.priority) {
|
|
3525
|
-
return b.priority - a.priority;
|
|
3526
|
-
}
|
|
3527
|
-
// If priorities are equal, maintain original order
|
|
3528
|
-
return tiles.indexOf(a) - tiles.indexOf(b);
|
|
3529
|
-
});
|
|
3530
|
-
};
|
|
3531
|
-
|
|
3532
3643
|
exports.SectionType = void 0;
|
|
3533
3644
|
(function (SectionType) {
|
|
3534
3645
|
SectionType["Grid"] = "GRID";
|
|
@@ -4003,7 +4114,7 @@ var useSectionData = function (section, sectionId) {
|
|
|
4003
4114
|
*/
|
|
4004
4115
|
var EmptyState = function (_a) {
|
|
4005
4116
|
var message = _a.message;
|
|
4006
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { style: commonStyles.emptyContainer,
|
|
4117
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { style: commonStyles.emptyContainer, role: "article", accessibilityLabel: "Empty state: ".concat(message), children: jsxRuntimeExports.jsx(reactNative.Text, { children: message }) }));
|
|
4007
4118
|
};
|
|
4008
4119
|
/**
|
|
4009
4120
|
* The Section component renders a section based on its type (e.g., Banner, Grid).
|
|
@@ -4072,6 +4183,14 @@ var useGroupContext = function () {
|
|
|
4072
4183
|
/**
|
|
4073
4184
|
* Custom hook to fetch and manage group data
|
|
4074
4185
|
*
|
|
4186
|
+
* This hook handles two distinct data fetching scenarios:
|
|
4187
|
+
* 1. Initial fetch: Shows loading state while first loading data
|
|
4188
|
+
* 2. Background refresh: Updates data silently without loading states
|
|
4189
|
+
*
|
|
4190
|
+
* The hook subscribes to GROUP_DATA_CHANGED events to refresh data
|
|
4191
|
+
* when notified by the host application, ensuring UI remains responsive
|
|
4192
|
+
* without showing loading indicators during refreshes.
|
|
4193
|
+
*
|
|
4075
4194
|
* @param {string} id - The ID of the group to fetch
|
|
4076
4195
|
* @returns {Object} Object containing group data, loading state, and any error
|
|
4077
4196
|
*/
|
|
@@ -4080,60 +4199,86 @@ var useGroupData = function (id) {
|
|
|
4080
4199
|
var _a = React.useState(null), groupData = _a[0], setGroupData = _a[1];
|
|
4081
4200
|
var _b = React.useState(null), error = _b[0], setError = _b[1];
|
|
4082
4201
|
var _c = React.useState(true), isLoading = _c[0], setIsLoading = _c[1];
|
|
4083
|
-
var
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
case 4:
|
|
4122
|
-
if (showLoading) {
|
|
4123
|
-
setIsLoading(false);
|
|
4124
|
-
}
|
|
4125
|
-
return [7 /*endfinally*/];
|
|
4126
|
-
case 5: return [2 /*return*/];
|
|
4127
|
-
}
|
|
4128
|
-
});
|
|
4202
|
+
var _d = React.useState(false), isInitialFetchDone = _d[0], setIsInitialFetchDone = _d[1];
|
|
4203
|
+
var initialFetch = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
4204
|
+
var response, err_1;
|
|
4205
|
+
return __generator(this, function (_a) {
|
|
4206
|
+
switch (_a.label) {
|
|
4207
|
+
case 0:
|
|
4208
|
+
if (!id || !sdk || !sdk.getGroupByID) {
|
|
4209
|
+
setError('Unable to fetch group data: invalid configuration');
|
|
4210
|
+
setIsLoading(false);
|
|
4211
|
+
setIsInitialFetchDone(true);
|
|
4212
|
+
return [2 /*return*/];
|
|
4213
|
+
}
|
|
4214
|
+
setIsLoading(true);
|
|
4215
|
+
setError(null);
|
|
4216
|
+
_a.label = 1;
|
|
4217
|
+
case 1:
|
|
4218
|
+
_a.trys.push([1, 3, 4, 5]);
|
|
4219
|
+
return [4 /*yield*/, sdk.refreshGroup(id)];
|
|
4220
|
+
case 2:
|
|
4221
|
+
response = _a.sent();
|
|
4222
|
+
if (response && response.status === 'success' && response.data) {
|
|
4223
|
+
setGroupData(response.data);
|
|
4224
|
+
}
|
|
4225
|
+
else {
|
|
4226
|
+
setError((response && response.error) || 'Failed to fetch group data.');
|
|
4227
|
+
}
|
|
4228
|
+
return [3 /*break*/, 5];
|
|
4229
|
+
case 3:
|
|
4230
|
+
err_1 = _a.sent();
|
|
4231
|
+
setError('Failed to fetch group data. Please try again later.');
|
|
4232
|
+
console.error('Error fetching group:', err_1);
|
|
4233
|
+
return [3 /*break*/, 5];
|
|
4234
|
+
case 4:
|
|
4235
|
+
setIsLoading(false);
|
|
4236
|
+
setIsInitialFetchDone(true);
|
|
4237
|
+
return [7 /*endfinally*/];
|
|
4238
|
+
case 5: return [2 /*return*/];
|
|
4239
|
+
}
|
|
4129
4240
|
});
|
|
4130
|
-
}, [id, sdk]);
|
|
4241
|
+
}); }, [id, sdk]);
|
|
4242
|
+
var silentRefresh = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
4243
|
+
var response, err_2;
|
|
4244
|
+
return __generator(this, function (_a) {
|
|
4245
|
+
switch (_a.label) {
|
|
4246
|
+
case 0:
|
|
4247
|
+
if (!id || !sdk || !sdk.getGroupByID || !isInitialFetchDone) {
|
|
4248
|
+
return [2 /*return*/];
|
|
4249
|
+
}
|
|
4250
|
+
_a.label = 1;
|
|
4251
|
+
case 1:
|
|
4252
|
+
_a.trys.push([1, 3, , 4]);
|
|
4253
|
+
return [4 /*yield*/, sdk.refreshGroup(id)];
|
|
4254
|
+
case 2:
|
|
4255
|
+
response = _a.sent();
|
|
4256
|
+
if (response && response.status === 'success' && response.data) {
|
|
4257
|
+
setGroupData(response.data);
|
|
4258
|
+
}
|
|
4259
|
+
return [3 /*break*/, 4];
|
|
4260
|
+
case 3:
|
|
4261
|
+
err_2 = _a.sent();
|
|
4262
|
+
console.error('Error during silent refresh:', err_2);
|
|
4263
|
+
return [3 /*break*/, 4];
|
|
4264
|
+
case 4: return [2 /*return*/];
|
|
4265
|
+
}
|
|
4266
|
+
});
|
|
4267
|
+
}); }, [id, sdk, isInitialFetchDone]);
|
|
4131
4268
|
var refreshGroup = React.useCallback(function () {
|
|
4132
|
-
return
|
|
4133
|
-
}, [
|
|
4269
|
+
return silentRefresh();
|
|
4270
|
+
}, [silentRefresh]);
|
|
4134
4271
|
React.useEffect(function () {
|
|
4135
|
-
|
|
4136
|
-
|
|
4272
|
+
if (sdk) {
|
|
4273
|
+
initialFetch();
|
|
4274
|
+
var unsubscribeGroup_1 = sdk.subscribeToDataChange('GROUP_DATA_CHANGED', function () {
|
|
4275
|
+
silentRefresh();
|
|
4276
|
+
});
|
|
4277
|
+
return function () {
|
|
4278
|
+
unsubscribeGroup_1();
|
|
4279
|
+
};
|
|
4280
|
+
}
|
|
4281
|
+
}, [initialFetch, id, sdk, silentRefresh]);
|
|
4137
4282
|
return { groupData: groupData, isLoading: isLoading, error: error, refreshGroup: refreshGroup };
|
|
4138
4283
|
};
|
|
4139
4284
|
/**
|
|
@@ -4191,7 +4336,7 @@ var Group = function (_a) {
|
|
|
4191
4336
|
if (error || !groupData) {
|
|
4192
4337
|
return jsxRuntimeExports.jsx(GroupEmptyState, { message: error || 'No group data available' });
|
|
4193
4338
|
}
|
|
4194
|
-
return (jsxRuntimeExports.jsx(GroupContext.Provider, { value: { groupData: groupData }, children: jsxRuntimeExports.jsx(reactNative.View, {
|
|
4339
|
+
return (jsxRuntimeExports.jsx(GroupContext.Provider, { value: { groupData: groupData }, children: jsxRuntimeExports.jsx(reactNative.View, { testID: "group-container", children: jsxRuntimeExports.jsx(GroupSections, {}) }) }));
|
|
4195
4340
|
};
|
|
4196
4341
|
|
|
4197
4342
|
/**
|
|
@@ -4404,7 +4549,7 @@ var PointsTileFormattedPoints = function () {
|
|
|
4404
4549
|
return null;
|
|
4405
4550
|
var calculatedPoints = applyMultiplier(points, pointsMultiplier);
|
|
4406
4551
|
var fullPointsText = "".concat(pointsPrefix).concat(calculatedPoints, " ").concat(pointsSuffix).trim();
|
|
4407
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { testID: "points-tile-points",
|
|
4552
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { testID: "points-tile-points", role: "article", accessibilityLabel: "Points value: ".concat(fullPointsText), children: jsxRuntimeExports.jsxs(Row, { align: "center", justify: "start", children: [pointsPrefix ? (jsxRuntimeExports.jsx(Text, { variant: "caption", testID: "points-tile-prefix", children: pointsPrefix })) : null, jsxRuntimeExports.jsx(Text, { variant: "caption", testID: "points-tile-value", children: calculatedPoints }), pointsSuffix ? (jsxRuntimeExports.jsx(Text, { variant: "caption", style: styles.suffix, testID: "points-tile-suffix", children: pointsSuffix })) : null] }) }));
|
|
4408
4553
|
};
|
|
4409
4554
|
|
|
4410
4555
|
/**
|
|
@@ -4421,7 +4566,7 @@ var PointsTileMedia = function (_a) {
|
|
|
4421
4566
|
var styles = usePointsTileStyles(isFullSize);
|
|
4422
4567
|
if (!artworkUrl)
|
|
4423
4568
|
return null;
|
|
4424
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { testID: "points-tile-media", style: styles.imageContainer,
|
|
4569
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { testID: "points-tile-media", style: styles.imageContainer, role: "img", accessibilityLabel: "Points tile image for ".concat(title), children: jsxRuntimeExports.jsx(reactNative.Image, { source: { uri: artworkUrl }, style: styles.image, resizeMode: isFullSize ? 'cover' : 'contain' }) }));
|
|
4425
4570
|
};
|
|
4426
4571
|
|
|
4427
4572
|
/**
|
|
@@ -4436,7 +4581,7 @@ var PointsTileTitle = function () {
|
|
|
4436
4581
|
var title = tileContext.configuration.title;
|
|
4437
4582
|
if (!title)
|
|
4438
4583
|
return null;
|
|
4439
|
-
return (jsxRuntimeExports.jsx(Text, { variant: "eyebrow", testID: "points-tile-title",
|
|
4584
|
+
return (jsxRuntimeExports.jsx(Text, { variant: "eyebrow", testID: "points-tile-title", role: "heading", accessibilityLabel: title, children: title }));
|
|
4440
4585
|
};
|
|
4441
4586
|
|
|
4442
4587
|
/**
|
|
@@ -4515,7 +4660,7 @@ var RewardCategoryHeader = function () {
|
|
|
4515
4660
|
var _a = tileContext.configuration, _b = _a.showName, showName = _b === void 0 ? true : _b, _c = _a.name, name = _c === void 0 ? '' : _c;
|
|
4516
4661
|
if (!showName || !name)
|
|
4517
4662
|
return null;
|
|
4518
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.header, { backgroundColor: theme.primary }], testID: "reward-category-header",
|
|
4663
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.header, { backgroundColor: theme.primary }], testID: "reward-category-header", role: "heading", accessibilityLabel: "Reward category: ".concat(name), children: jsxRuntimeExports.jsx(Text, { style: [styles.headerText, { color: theme.primaryText }], ellipsizeMode: "tail", numberOfLines: 1, children: name }) }));
|
|
4519
4664
|
};
|
|
4520
4665
|
|
|
4521
4666
|
/**
|
|
@@ -4531,7 +4676,7 @@ var RewardCategoryMedia = function () {
|
|
|
4531
4676
|
var _a = tileContext.configuration, artworkUrl = _a.artworkUrl, _b = _a.name, name = _b === void 0 ? 'Reward' : _b;
|
|
4532
4677
|
if (!artworkUrl)
|
|
4533
4678
|
return null;
|
|
4534
|
-
return (jsxRuntimeExports.jsx(ProgressiveImage, { testID: "reward-category-media", source: { uri: artworkUrl }, style: styles.background, alt: "Reward category image for ".concat(name),
|
|
4679
|
+
return (jsxRuntimeExports.jsx(ProgressiveImage, { testID: "reward-category-media", source: { uri: artworkUrl }, style: styles.background, alt: "Reward category image for ".concat(name), role: "img" }));
|
|
4535
4680
|
};
|
|
4536
4681
|
|
|
4537
4682
|
/**
|
|
@@ -4564,7 +4709,7 @@ var RewardCategoryTile$1 = withTileFetching(RewardCategoryTile);
|
|
|
4564
4709
|
var RewardTileChevron = function () {
|
|
4565
4710
|
var _a;
|
|
4566
4711
|
var theme = useWllSdk().theme;
|
|
4567
|
-
return (jsxRuntimeExports.jsx(Icon, { name: "ChevronRight", size: IS_MOBILE ? 16 : undefined, color: ((_a = theme === null || theme === void 0 ? void 0 : theme.derivedSurfaceText) === null || _a === void 0 ? void 0 : _a[20]) || '#000000',
|
|
4712
|
+
return (jsxRuntimeExports.jsx(Icon, { name: "ChevronRight", size: IS_MOBILE ? 16 : undefined, color: ((_a = theme === null || theme === void 0 ? void 0 : theme.derivedSurfaceText) === null || _a === void 0 ? void 0 : _a[20]) || '#000000', role: "img", accessibilityLabel: "View reward details" }));
|
|
4568
4713
|
};
|
|
4569
4714
|
|
|
4570
4715
|
/**
|
|
@@ -4638,7 +4783,7 @@ var RewardTileMedia = function (_a) {
|
|
|
4638
4783
|
var containerStyle = {
|
|
4639
4784
|
flexBasis: isArtworkOnly ? '100%' : '50%',
|
|
4640
4785
|
};
|
|
4641
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.imageContainer, containerStyle], testID: "reward-tile-media",
|
|
4786
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.imageContainer, containerStyle], testID: "reward-tile-media", role: "img", accessibilityLabel: "Reward image for ".concat(name), children: jsxRuntimeExports.jsx(ProgressiveImage, { source: { uri: artworkUrl }, style: styles.image, alt: "Reward image for ".concat(name) }) }));
|
|
4642
4787
|
};
|
|
4643
4788
|
|
|
4644
4789
|
/**
|
|
@@ -4656,7 +4801,7 @@ var RewardTilePoints = function () {
|
|
|
4656
4801
|
return null;
|
|
4657
4802
|
var calculatedPoints = applyMultiplier(price, pointsMultiplier);
|
|
4658
4803
|
var accessibilityLabel = getPointsLabel('Reward points:', calculatedPoints, pointsPrefix, pointsSuffix);
|
|
4659
|
-
return (jsxRuntimeExports.jsx(reactNative.View, { testID: "reward-tile-points",
|
|
4804
|
+
return (jsxRuntimeExports.jsx(reactNative.View, { testID: "reward-tile-points", role: "article", accessibilityLabel: accessibilityLabel, children: jsxRuntimeExports.jsxs(Row, { align: "center", justify: "start", style: { marginTop: 8 }, children: [pointsPrefix ? jsxRuntimeExports.jsx(Text, { variant: "caption", children: pointsPrefix }) : null, jsxRuntimeExports.jsx(Text, { variant: "caption", testID: "reward-tile-points-value", children: calculatedPoints }), pointsSuffix ? (jsxRuntimeExports.jsx(Text, { variant: "caption", style: styles.suffix, children: pointsSuffix })) : null] }) }));
|
|
4660
4805
|
};
|
|
4661
4806
|
|
|
4662
4807
|
/**
|
|
@@ -4671,7 +4816,7 @@ var RewardTileSummary = function () {
|
|
|
4671
4816
|
var summary = tileContext.configuration.summary;
|
|
4672
4817
|
if (!summary)
|
|
4673
4818
|
return null;
|
|
4674
|
-
return (jsxRuntimeExports.jsx(Text, { variant: "body",
|
|
4819
|
+
return (jsxRuntimeExports.jsx(Text, { variant: "body", role: "article", accessibilityLabel: summary, testID: "reward-tile-summary", children: summary }));
|
|
4675
4820
|
};
|
|
4676
4821
|
|
|
4677
4822
|
/**
|
|
@@ -4692,7 +4837,7 @@ var RewardTileTitle = function () {
|
|
|
4692
4837
|
return styles.titleWithLink;
|
|
4693
4838
|
}
|
|
4694
4839
|
};
|
|
4695
|
-
return (jsxRuntimeExports.jsx(Text, { variant: "title", ellipsizeMode: "tail", numberOfLines: 1,
|
|
4840
|
+
return (jsxRuntimeExports.jsx(Text, { variant: "title", ellipsizeMode: "tail", numberOfLines: 1, role: "heading", accessibilityLabel: "Reward title: ".concat(name), testID: "reward-tile-title", style: handleTitleWidth(), children: name }));
|
|
4696
4841
|
};
|
|
4697
4842
|
|
|
4698
4843
|
/**
|