@wlloyalty/wll-react-sdk 1.10.0 → 1.11.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/dist/index.d.ts CHANGED
@@ -93,7 +93,8 @@ declare enum TileType {
93
93
  RewardCategory = "REWARD_CATEGORY",
94
94
  Tier = "TIER",
95
95
  Roundup = "ROUND_UP_BALANCE",
96
- Venue = "VENUE"
96
+ Venue = "VENUE",
97
+ Campaign = "EARNING_CAMPAIGN"
97
98
  }
98
99
  declare enum TileHeight {
99
100
  Half = "HALF",
@@ -248,6 +249,46 @@ declare class TierTileConfig {
248
249
  pointsToTierSuffix?: string;
249
250
  locale: string;
250
251
  }
252
+ declare class CampaignTileConfig {
253
+ campaignId: string;
254
+ type: string;
255
+ status: string;
256
+ name: string;
257
+ description: string;
258
+ artworkUrl: string;
259
+ showDetails?: boolean;
260
+ effectivity: {
261
+ start: Date | null;
262
+ end: Date | null;
263
+ };
264
+ progress: CampaignProgress | null;
265
+ missions: CampaignMission[];
266
+ }
267
+ type CampaignProgress = {
268
+ currentValue: number;
269
+ targetValue: number;
270
+ windowStart: string | null;
271
+ windowEnd: string | null;
272
+ optedInAt: string | null;
273
+ completedAt: string | null;
274
+ availableAgainAt: string | null;
275
+ cooldownCycle: number | null;
276
+ };
277
+ type CampaignMission = {
278
+ id: string;
279
+ name: string;
280
+ description: string | null;
281
+ pictureUrl: string | null;
282
+ completionType: string;
283
+ targetValue: number;
284
+ displayStyle: string;
285
+ requiresOptIn: boolean;
286
+ lockState: string;
287
+ order: number;
288
+ duration: number | null;
289
+ cooldownDuration: number | null;
290
+ progress: CampaignProgress;
291
+ };
251
292
  type Tile = {
252
293
  id: string | null;
253
294
  type?: TileType;
@@ -258,7 +299,7 @@ type Tile = {
258
299
  configuration: TileConfig;
259
300
  priority: number;
260
301
  };
261
- declare const getConfigForTileType: (tileType: TileType) => typeof BannerTileConfig | typeof PointsTileConfig | typeof ContentTileConfig | typeof RewardTileConfig | typeof VenueTileConfig | typeof BadgeTileConfig | typeof RewardCategoryTileConfig | typeof TierTileConfig;
302
+ declare const getConfigForTileType: (tileType: TileType) => typeof BannerTileConfig | typeof PointsTileConfig | typeof ContentTileConfig | typeof RewardTileConfig | typeof VenueTileConfig | typeof BadgeTileConfig | typeof RewardCategoryTileConfig | typeof TierTileConfig | typeof CampaignTileConfig;
262
303
  type TileConfig = InstanceType<ReturnType<typeof getConfigForTileType>>;
263
304
  type TileSizeInfo = {
264
305
  isFullSize: boolean;
@@ -354,8 +395,11 @@ type ProgressBarProps = {
354
395
  variant?: Variant;
355
396
  height?: Size;
356
397
  animationDuration?: number;
398
+ currentValue?: number;
399
+ targetValue?: number;
400
+ showProgressLabel?: boolean;
357
401
  };
358
- declare const ProgressBar: ({ percentage, variant, height, animationDuration, }: ProgressBarProps) => React$1.ReactElement;
402
+ declare const ProgressBar: ({ percentage, variant, height, animationDuration, currentValue, targetValue, showProgressLabel, }: ProgressBarProps) => React$1.ReactElement;
359
403
 
360
404
  type ProgressiveImageProps = {
361
405
  source: ImageSourcePropType;
@@ -611,12 +655,17 @@ type WithTileFetchingProps = {
611
655
  type BadgeTileProps = {
612
656
  tile: Tile;
613
657
  };
614
- declare const _default$7: (props: Omit<BadgeTileProps, "tile"> & WithTileFetchingProps) => React__default.JSX.Element;
658
+ declare const _default$8: (props: Omit<BadgeTileProps, "tile"> & WithTileFetchingProps) => React__default.JSX.Element;
615
659
 
616
660
  type BannerTileProps = {
617
661
  tile: Tile;
618
662
  };
619
- declare const _default$6: (props: Omit<BannerTileProps, "tile"> & WithTileFetchingProps) => React__default.JSX.Element;
663
+ declare const _default$7: (props: Omit<BannerTileProps, "tile"> & WithTileFetchingProps) => React__default.JSX.Element;
664
+
665
+ type CampaignTileProps = {
666
+ tile: Tile;
667
+ };
668
+ declare const _default$6: (props: Omit<CampaignTileProps, "tile"> & WithTileFetchingProps) => React__default.JSX.Element;
620
669
 
621
670
  type ContentTileProps = {
622
671
  tile: Tile;
@@ -1046,5 +1095,5 @@ declare const useInitialGroupFetch: ({ id, setGroupData, }: UseInitialGroupFetch
1046
1095
 
1047
1096
  declare const useNavigation: (config: NavigationConfig) => (link: string, ctaTarget: CTALinkTarget) => Promise<void>;
1048
1097
 
1049
- export { BUTTON_SIZE, _default$7 as BadgeTile, BadgeTileConfig, BadgeTileType, _default$6 as BannerTile, BannerTileConfig, BaseBanner, BaseTile, Button, COLOR_CONSTANTS, CTALinkTarget, Carousel, CarouselNavButton, Chip, Column, _default$5 as ContentTile, ContentTileConfig, CoreApiUrl, DIMENSION_MODES, EventEmitter, FullFlex, GRID_GAP, Grid, Group, IS_ANDROID, IS_DESKTOP, IS_IOS, IS_MOBILE, IS_WEB, Icon, Indicator, Layout, LoadingIndicator, MAX_WIDTH, _default$4 as PointsTile, PointsTileConfig, ProgressBar, ProgressIndicator, ProgressType, ProgressiveImage, Reward, _default$3 as RewardCategoryTile, RewardCategoryTileConfig, _default$2 as RewardTile, RewardTileConfig, _default$1 as RoundupTile, RoundupTileConfig, Row, SCREEN_HEIGHT, SCREEN_WIDTH, SLIDE_WIDTH, SMALL_SCREEN_WIDTH, Section, SectionHeader, SectionType, Skeleton, Spacer, StatusVariant, TABLET_SCREEN_WIDTH, Text, TierTileConfig, TierTileType, TierTile as TierTileUpdated, TileContainer, TileHeight, TileType, _default as VenueTile, VenueTileConfig, WllSdkProvider, alignMap, commonStyles, createResourceGetter, defaultTheme, desaturateColor, getAlphaDerivedColors, getDerivedColor, getDerivedColorPercentages, getDimensionMode, getDirectionalMargin, getReadableTextColor, getResponsiveValue, getStateColor, handleLastEarnedDate, justifyMap, sdkEventEmitter, shouldDesaturate, sizes, sortByPriority, themeItems, themes, transformLocale, useCreateRequestOptions, useGetGroupByID, useGetSectionByID, useGetTileByID, useGroupRefresh, useInitialGroupFetch, useInvalidateData, useMakeRequest, useNavigation, usePullToRefresh, useResponsive, useResponsiveValue, useTileSize, useWllSdk, validateTheme };
1050
- export type { APIResponse$1 as APIResponse, Align, AllowedCoreApiUrl, Availability, Badge, BadgeDetail, BaseThemeObject, DerivedColors, DerivedProperties, DesaturationType, EventCallback, EventTypes, FlexDirection, ImagePropsNoSource, Justify, LayoutProps$1 as LayoutProps, NavigationConfig, NavigationType, PercentageKey, ProgessType, RewardCategory, SDKConfig, Size, Sizes, TGroup, TSection, ThemeContextType, ThemeName, ThemeObject, ThemeProviderProps, TierType, Tile, TileConfig, TileSizeInfo, Variant };
1098
+ export { BUTTON_SIZE, _default$8 as BadgeTile, BadgeTileConfig, BadgeTileType, _default$7 as BannerTile, BannerTileConfig, BaseBanner, BaseTile, Button, COLOR_CONSTANTS, CTALinkTarget, _default$6 as CampaignTile, CampaignTileConfig, Carousel, CarouselNavButton, Chip, Column, _default$5 as ContentTile, ContentTileConfig, CoreApiUrl, DIMENSION_MODES, EventEmitter, FullFlex, GRID_GAP, Grid, Group, IS_ANDROID, IS_DESKTOP, IS_IOS, IS_MOBILE, IS_WEB, Icon, Indicator, Layout, LoadingIndicator, MAX_WIDTH, _default$4 as PointsTile, PointsTileConfig, ProgressBar, ProgressIndicator, ProgressType, ProgressiveImage, Reward, _default$3 as RewardCategoryTile, RewardCategoryTileConfig, _default$2 as RewardTile, RewardTileConfig, _default$1 as RoundupTile, RoundupTileConfig, Row, SCREEN_HEIGHT, SCREEN_WIDTH, SLIDE_WIDTH, SMALL_SCREEN_WIDTH, Section, SectionHeader, SectionType, Skeleton, Spacer, StatusVariant, TABLET_SCREEN_WIDTH, Text, TierTileConfig, TierTileType, TierTile as TierTileUpdated, TileContainer, TileHeight, TileType, _default as VenueTile, VenueTileConfig, WllSdkProvider, alignMap, commonStyles, createResourceGetter, defaultTheme, desaturateColor, getAlphaDerivedColors, getDerivedColor, getDerivedColorPercentages, getDimensionMode, getDirectionalMargin, getReadableTextColor, getResponsiveValue, getStateColor, handleLastEarnedDate, justifyMap, sdkEventEmitter, shouldDesaturate, sizes, sortByPriority, themeItems, themes, transformLocale, useCreateRequestOptions, useGetGroupByID, useGetSectionByID, useGetTileByID, useGroupRefresh, useInitialGroupFetch, useInvalidateData, useMakeRequest, useNavigation, usePullToRefresh, useResponsive, useResponsiveValue, useTileSize, useWllSdk, validateTheme };
1099
+ export type { APIResponse$1 as APIResponse, Align, AllowedCoreApiUrl, Availability, Badge, BadgeDetail, BaseThemeObject, CampaignMission, CampaignProgress, DerivedColors, DerivedProperties, DesaturationType, EventCallback, EventTypes, FlexDirection, ImagePropsNoSource, Justify, LayoutProps$1 as LayoutProps, NavigationConfig, NavigationType, PercentageKey, ProgessType, RewardCategory, SDKConfig, Size, Sizes, TGroup, TSection, ThemeContextType, ThemeName, ThemeObject, ThemeProviderProps, TierType, Tile, TileConfig, TileSizeInfo, Variant };
package/dist/native.js CHANGED
@@ -1331,10 +1331,93 @@ var styles$8 = reactNative.StyleSheet.create({
1331
1331
  },
1332
1332
  });
1333
1333
 
1334
+ var Text = function (_a) {
1335
+ var _b = _a.variant, variant = _b === void 0 ? 'body' : _b, style = _a.style; _a.isSurface; var props = __rest(_a, ["variant", "style", "isSurface"]);
1336
+ var theme = useWllSdk().theme;
1337
+ var _d = useResponsive(), isDesktop = _d.isDesktop, isTablet = _d.isTablet;
1338
+ var getVariantStyle = function (variant) {
1339
+ var baseStyle = {
1340
+ color: theme.surfaceText,
1341
+ };
1342
+ switch (variant) {
1343
+ case 'eyebrow':
1344
+ return __assign(__assign({}, baseStyle), { fontSize: useResponsiveValue(theme.sizes.md, theme.sizes.sm, isDesktop, isTablet), marginBottom: useResponsiveValue(theme.sizes.xxs, theme.sizes.xxxs, isDesktop, isTablet) });
1345
+ case 'title':
1346
+ return __assign(__assign({}, baseStyle), { fontSize: useResponsiveValue(theme.sizes.xl, theme.sizes.md, isDesktop, isTablet), fontWeight: 'bold' });
1347
+ case 'body':
1348
+ return {
1349
+ color: theme.derivedSurfaceText[20],
1350
+ fontSize: useResponsiveValue(theme.sizes.md, theme.sizes.sm, isDesktop, isTablet),
1351
+ };
1352
+ case 'caption':
1353
+ return __assign(__assign({}, baseStyle), { fontWeight: 'bold', fontSize: useResponsiveValue(theme.sizes.xxl, theme.sizes.xl, isDesktop, isTablet), color: theme.primary });
1354
+ case 'description':
1355
+ case 'label':
1356
+ default:
1357
+ return __assign(__assign({}, baseStyle), { fontSize: useResponsiveValue(theme.sizes.sm, theme.sizes.xxs, isDesktop, isTablet) });
1358
+ }
1359
+ };
1360
+ var variantStyle = getVariantStyle(variant);
1361
+ // NOTE: React Native Web has different style resolution rules compared to CSS.
1362
+ // 1. We create styles using StyleSheet.create for better performance
1363
+ // 2. Base styles set the initial fontFamily
1364
+ // 3. variantStyle contains responsive fontSize and other variant-specific styles
1365
+ // 4. webOverrides ensures fontFamily is correctly applied on web platform
1366
+ // (prevents system font stack from being incorrectly applied)
1367
+ // 5. custom style prop has highest precedence
1368
+ // The order matters because RN Web resolves styles by specific properties
1369
+ // rather than last-declaration-wins like in CSS
1370
+ // https://necolas.github.io/react-native-web/docs/styling/#how-it-works
1371
+ var styles = reactNative.StyleSheet.create({
1372
+ base: {
1373
+ fontFamily: theme.fontFamily,
1374
+ },
1375
+ webOverrides: IS_WEB
1376
+ ? {
1377
+ fontFamily: theme.fontFamily,
1378
+ }
1379
+ : {},
1380
+ });
1381
+ // Determine appropriate accessibility role based on variant
1382
+ // This helps screen readers understand the semantic meaning
1383
+ var accessibilityRole;
1384
+ switch (variant) {
1385
+ case 'title':
1386
+ accessibilityRole = IS_MOBILE ? 'heading' : 'header';
1387
+ break;
1388
+ case 'caption':
1389
+ accessibilityRole = IS_MOBILE ? 'contentinfo' : 'text';
1390
+ break;
1391
+ case 'eyebrow':
1392
+ accessibilityRole = IS_MOBILE ? 'contentinfo' : 'text';
1393
+ break;
1394
+ case 'description':
1395
+ accessibilityRole = IS_MOBILE ? 'article' : 'paragraph';
1396
+ break;
1397
+ case 'label':
1398
+ accessibilityRole = IS_MOBILE ? 'option' : 'text';
1399
+ break;
1400
+ default:
1401
+ accessibilityRole = IS_MOBILE ? 'contentinfo' : 'text';
1402
+ }
1403
+ var combinedStyles = [
1404
+ styles.base,
1405
+ variantStyle,
1406
+ styles.webOverrides,
1407
+ style,
1408
+ ];
1409
+ return (jsxRuntimeExports.jsx(reactNative.Text, __assign({ style: combinedStyles }, props, { accessible: true, role: accessibilityRole })));
1410
+ };
1411
+
1334
1412
  var useStyles = function (theme) {
1335
1413
  return reactNative.StyleSheet.create({
1336
- container: {
1414
+ wrapper: {
1415
+ flexDirection: 'row',
1416
+ alignItems: 'center',
1337
1417
  width: '100%',
1418
+ },
1419
+ container: {
1420
+ flex: 1,
1338
1421
  borderRadius: theme.sizes.borderRadiusRounded,
1339
1422
  overflow: 'hidden',
1340
1423
  },
@@ -1342,6 +1425,21 @@ var useStyles = function (theme) {
1342
1425
  borderRadius: theme.sizes.borderRadiusRounded,
1343
1426
  height: '100%',
1344
1427
  },
1428
+ labelContainer: {
1429
+ flexDirection: 'row',
1430
+ alignItems: 'baseline',
1431
+ marginLeft: 8,
1432
+ flexShrink: 0,
1433
+ },
1434
+ labelCurrent: {
1435
+ fontSize: 15,
1436
+ fontWeight: 'bold',
1437
+ color: theme.primary,
1438
+ },
1439
+ labelTarget: {
1440
+ fontSize: 12,
1441
+ color: theme.derivedSurfaceText[20],
1442
+ },
1345
1443
  });
1346
1444
  };
1347
1445
  var useContainerStyles = function (theme) { return ({
@@ -1358,7 +1456,7 @@ function (theme) { return ({ borderRadius: theme.sizes.borderRadiusSmRounded });
1358
1456
  negative: { backgroundColor: theme.negative },
1359
1457
  }); });
1360
1458
  var ProgressBar = function (_a) {
1361
- var percentage = _a.percentage, _b = _a.variant, variant = _b === void 0 ? 'primary' : _b, _c = _a.height, height = _c === void 0 ? 'sm' : _c, _d = _a.animationDuration, animationDuration = _d === void 0 ? 300 : _d;
1459
+ var percentage = _a.percentage, _b = _a.variant, variant = _b === void 0 ? 'primary' : _b, _c = _a.height, height = _c === void 0 ? 'sm' : _c, _d = _a.animationDuration, animationDuration = _d === void 0 ? 300 : _d, currentValue = _a.currentValue, targetValue = _a.targetValue, _e = _a.showProgressLabel, showProgressLabel = _e === void 0 ? false : _e;
1362
1460
  var theme = useWllSdk().theme;
1363
1461
  var styles = useStyles(theme);
1364
1462
  var containerStyles = useContainerStyles(theme);
@@ -1382,7 +1480,13 @@ var ProgressBar = function (_a) {
1382
1480
  outputRange: ['0%', '100%'],
1383
1481
  }),
1384
1482
  };
1385
- return (jsxRuntimeExports.jsx(reactNative.View, { style: containerStyle, children: jsxRuntimeExports.jsx(reactNative.Animated.View, { style: [styles.progress, progressStyles, progressWidth] }) }));
1483
+ var shouldShowLabel = showProgressLabel &&
1484
+ currentValue !== undefined &&
1485
+ targetValue !== undefined;
1486
+ if (!shouldShowLabel) {
1487
+ return (jsxRuntimeExports.jsx(reactNative.View, { style: [containerStyle, { width: '100%' }], children: jsxRuntimeExports.jsx(reactNative.Animated.View, { style: [styles.progress, progressStyles, progressWidth] }) }));
1488
+ }
1489
+ return (jsxRuntimeExports.jsxs(reactNative.View, { style: styles.wrapper, children: [jsxRuntimeExports.jsx(reactNative.View, { style: [containerStyle], children: jsxRuntimeExports.jsx(reactNative.Animated.View, { style: [styles.progress, progressStyles, progressWidth] }) }), jsxRuntimeExports.jsxs(reactNative.View, { style: styles.labelContainer, accessibilityLabel: "".concat(currentValue, " of ").concat(targetValue, " completed"), children: [jsxRuntimeExports.jsx(Text, { style: styles.labelCurrent, children: currentValue }), jsxRuntimeExports.jsx(Text, { style: styles.labelTarget, children: " / ".concat(targetValue) })] })] }));
1386
1490
  };
1387
1491
 
1388
1492
  exports.CTALinkTarget = void 0;
@@ -1411,6 +1515,7 @@ exports.TileType = void 0;
1411
1515
  TileType["Tier"] = "TIER";
1412
1516
  TileType["Roundup"] = "ROUND_UP_BALANCE";
1413
1517
  TileType["Venue"] = "VENUE";
1518
+ TileType["Campaign"] = "EARNING_CAMPAIGN";
1414
1519
  })(exports.TileType || (exports.TileType = {}));
1415
1520
  exports.TileHeight = void 0;
1416
1521
  (function (TileHeight) {
@@ -1543,6 +1648,32 @@ var TierTileConfig = /** @class */ (function () {
1543
1648
  }
1544
1649
  return TierTileConfig;
1545
1650
  }());
1651
+ var CampaignTileConfig = /** @class */ (function () {
1652
+ function CampaignTileConfig() {
1653
+ this.campaignId = '';
1654
+ this.type = '';
1655
+ this.status = '';
1656
+ this.name = '';
1657
+ this.description = '';
1658
+ this.artworkUrl = '';
1659
+ this.effectivity = {
1660
+ start: null,
1661
+ end: null
1662
+ };
1663
+ this.progress = {
1664
+ currentValue: 0,
1665
+ targetValue: 0,
1666
+ windowStart: null,
1667
+ windowEnd: null,
1668
+ optedInAt: null,
1669
+ completedAt: null,
1670
+ availableAgainAt: null,
1671
+ cooldownCycle: null,
1672
+ };
1673
+ this.missions = [];
1674
+ }
1675
+ return CampaignTileConfig;
1676
+ }());
1546
1677
 
1547
1678
  var useHandleTilePress = function (tile, ctaLink, ctaLinkTarget) {
1548
1679
  var handleNavigation = useWllSdk().handleNavigation;
@@ -1563,8 +1694,15 @@ var useHandleTilePress = function (tile, ctaLink, ctaLinkTarget) {
1563
1694
  }
1564
1695
  if ((tile === null || tile === void 0 ? void 0 : tile.type) === exports.TileType.RewardCategory) {
1565
1696
  var config = tile.configuration;
1566
- var url = "/category?id=".concat(config.rewardCategoryId);
1567
1697
  if (config === null || config === void 0 ? void 0 : config.rewardCategoryId) {
1698
+ var url = "/category?id=".concat(config.rewardCategoryId);
1699
+ return handleNavigation(url, exports.CTALinkTarget.sameWindow);
1700
+ }
1701
+ }
1702
+ if ((tile === null || tile === void 0 ? void 0 : tile.type) === exports.TileType.Campaign) {
1703
+ var config = tile.configuration;
1704
+ if (config === null || config === void 0 ? void 0 : config.campaignId) {
1705
+ var url = "/campaigns/".concat(config.campaignId);
1568
1706
  return handleNavigation(url, exports.CTALinkTarget.sameWindow);
1569
1707
  }
1570
1708
  }
@@ -1582,84 +1720,6 @@ var useTileSize = function (tile) {
1582
1720
  }); }, [tile.tileHeight]);
1583
1721
  };
1584
1722
 
1585
- var Text = function (_a) {
1586
- var _b = _a.variant, variant = _b === void 0 ? 'body' : _b, style = _a.style; _a.isSurface; var props = __rest(_a, ["variant", "style", "isSurface"]);
1587
- var theme = useWllSdk().theme;
1588
- var _d = useResponsive(), isDesktop = _d.isDesktop, isTablet = _d.isTablet;
1589
- var getVariantStyle = function (variant) {
1590
- var baseStyle = {
1591
- color: theme.surfaceText,
1592
- };
1593
- switch (variant) {
1594
- case 'eyebrow':
1595
- return __assign(__assign({}, baseStyle), { fontSize: useResponsiveValue(theme.sizes.md, theme.sizes.sm, isDesktop, isTablet), marginBottom: useResponsiveValue(theme.sizes.xxs, theme.sizes.xxxs, isDesktop, isTablet) });
1596
- case 'title':
1597
- return __assign(__assign({}, baseStyle), { fontSize: useResponsiveValue(theme.sizes.xl, theme.sizes.md, isDesktop, isTablet), fontWeight: 'bold' });
1598
- case 'body':
1599
- return {
1600
- color: theme.derivedSurfaceText[20],
1601
- fontSize: useResponsiveValue(theme.sizes.md, theme.sizes.sm, isDesktop, isTablet),
1602
- };
1603
- case 'caption':
1604
- return __assign(__assign({}, baseStyle), { fontWeight: 'bold', fontSize: useResponsiveValue(theme.sizes.xxl, theme.sizes.xl, isDesktop, isTablet), color: theme.primary });
1605
- case 'description':
1606
- case 'label':
1607
- default:
1608
- return __assign(__assign({}, baseStyle), { fontSize: useResponsiveValue(theme.sizes.sm, theme.sizes.xxs, isDesktop, isTablet) });
1609
- }
1610
- };
1611
- var variantStyle = getVariantStyle(variant);
1612
- // NOTE: React Native Web has different style resolution rules compared to CSS.
1613
- // 1. We create styles using StyleSheet.create for better performance
1614
- // 2. Base styles set the initial fontFamily
1615
- // 3. variantStyle contains responsive fontSize and other variant-specific styles
1616
- // 4. webOverrides ensures fontFamily is correctly applied on web platform
1617
- // (prevents system font stack from being incorrectly applied)
1618
- // 5. custom style prop has highest precedence
1619
- // The order matters because RN Web resolves styles by specific properties
1620
- // rather than last-declaration-wins like in CSS
1621
- // https://necolas.github.io/react-native-web/docs/styling/#how-it-works
1622
- var styles = reactNative.StyleSheet.create({
1623
- base: {
1624
- fontFamily: theme.fontFamily,
1625
- },
1626
- webOverrides: IS_WEB
1627
- ? {
1628
- fontFamily: theme.fontFamily,
1629
- }
1630
- : {},
1631
- });
1632
- // Determine appropriate accessibility role based on variant
1633
- // This helps screen readers understand the semantic meaning
1634
- var accessibilityRole;
1635
- switch (variant) {
1636
- case 'title':
1637
- accessibilityRole = IS_MOBILE ? 'heading' : 'header';
1638
- break;
1639
- case 'caption':
1640
- accessibilityRole = IS_MOBILE ? 'contentinfo' : 'text';
1641
- break;
1642
- case 'eyebrow':
1643
- accessibilityRole = IS_MOBILE ? 'contentinfo' : 'text';
1644
- break;
1645
- case 'description':
1646
- accessibilityRole = IS_MOBILE ? 'article' : 'paragraph';
1647
- break;
1648
- case 'label':
1649
- accessibilityRole = IS_MOBILE ? 'option' : 'text';
1650
- break;
1651
- default:
1652
- accessibilityRole = IS_MOBILE ? 'contentinfo' : 'text';
1653
- }
1654
- var combinedStyles = [
1655
- styles.base,
1656
- variantStyle,
1657
- styles.webOverrides,
1658
- style,
1659
- ];
1660
- return (jsxRuntimeExports.jsx(reactNative.Text, __assign({ style: combinedStyles }, props, { accessible: true, role: accessibilityRole })));
1661
- };
1662
-
1663
1723
  /**
1664
1724
  * Renders the body text of a BaseTile component.
1665
1725
  *
@@ -1930,10 +1990,13 @@ var BaseTileContainer = function (_a) {
1930
1990
  var _b = tile.configuration, _c = _b.ctaLink, ctaLink = _c === void 0 ? '' : _c, ctaLinkTarget = _b.ctaLinkTarget, _d = _b.title, title = _d === void 0 ? 'Tile' : _d;
1931
1991
  var theme = (sdk === null || sdk === void 0 ? void 0 : sdk.theme) || { surface: '#ffffff' };
1932
1992
  var handlePress = useHandleTilePress(tile, ctaLink, ctaLinkTarget);
1933
- var isInteractive = Boolean(ctaLink ||
1934
- tile.type === 'REWARD' ||
1935
- tile.type === 'REWARD_CATEGORY' ||
1936
- tile.type === 'VENUE');
1993
+ var interactiveTiles = [
1994
+ exports.TileType.Reward,
1995
+ exports.TileType.RewardCategory,
1996
+ exports.TileType.Venue,
1997
+ exports.TileType.Campaign
1998
+ ];
1999
+ var isInteractive = Boolean(ctaLink || (tile.type && interactiveTiles.includes(tile.type)));
1937
2000
  var layout = {
1938
2001
  flexDirection: 'column',
1939
2002
  justifyContent: isHalfSize ? 'center' : 'flex-start',
@@ -2680,7 +2743,7 @@ var BannerTileTitle = function () {
2680
2743
  * @param configuration - The configuration object of the tile.
2681
2744
  * @returns `true` if the tile has no title, description, or CTA text.
2682
2745
  */
2683
- var isArtworkOnly$2 = function (configuration) {
2746
+ var isArtworkOnly$3 = function (configuration) {
2684
2747
  if (!configuration)
2685
2748
  return true;
2686
2749
  return (!configuration.title && !configuration.description && !configuration.ctaText);
@@ -2698,7 +2761,7 @@ var BannerTileRoot = function (_a) {
2698
2761
  if (!tile || !tile.active || !tile.configuration)
2699
2762
  return null;
2700
2763
  var configuration = tile.configuration;
2701
- return (jsxRuntimeExports.jsxs(BaseBanner, { tile: tile, children: [jsxRuntimeExports.jsx(BannerTile.Media, { isArtworkOnly: isArtworkOnly$2(configuration) }), jsxRuntimeExports.jsxs(FullFlex, { children: [jsxRuntimeExports.jsx(BannerTile.Title, {}), jsxRuntimeExports.jsx(BannerTile.Description, {}), jsxRuntimeExports.jsx(BannerTile.CTA, {})] })] }));
2764
+ return (jsxRuntimeExports.jsxs(BaseBanner, { tile: tile, children: [jsxRuntimeExports.jsx(BannerTile.Media, { isArtworkOnly: isArtworkOnly$3(configuration) }), jsxRuntimeExports.jsxs(FullFlex, { children: [jsxRuntimeExports.jsx(BannerTile.Title, {}), jsxRuntimeExports.jsx(BannerTile.Description, {}), jsxRuntimeExports.jsx(BannerTile.CTA, {})] })] }));
2702
2765
  };
2703
2766
  /**
2704
2767
  * The BannerTile component with subcomponents attached.
@@ -2711,6 +2774,173 @@ var BannerTile = Object.assign(BannerTileRoot, {
2711
2774
  });
2712
2775
  var BannerTile$1 = withTileFetching(BannerTile);
2713
2776
 
2777
+ /**
2778
+ * Renders the description of a Campaign Tile.
2779
+ *
2780
+ * @returns React.ReactElement or null if no description is present
2781
+ */
2782
+ var CampaignTileDescription = function () {
2783
+ var tileContext = useTileContext();
2784
+ if (!isContextValid(tileContext))
2785
+ return null;
2786
+ var description = tileContext.configuration.description;
2787
+ if (!description)
2788
+ return null;
2789
+ return (jsxRuntimeExports.jsx(Text, { variant: "body", role: "article", accessibilityLabel: description, testID: "campaign-tile-description", numberOfLines: 2, ellipsizeMode: "tail", children: description }));
2790
+ };
2791
+
2792
+ /**
2793
+ * Custom hook that returns the styles for the CampaignTile component.
2794
+ * Applies responsive styling based on the current device.
2795
+ *
2796
+ * @returns StyleSheet styles for the CampaignTile component
2797
+ */
2798
+ var useCampaignTileStyles = function () {
2799
+ var _a = useResponsive$1(), isDesktop = _a.isDesktop, isTablet = _a.isTablet;
2800
+ var theme = useWllSdk().theme;
2801
+ return reactNative.StyleSheet.create({
2802
+ imageContainer: {
2803
+ width: '100%',
2804
+ minHeight: 130,
2805
+ },
2806
+ image: {
2807
+ width: '100%',
2808
+ height: '100%',
2809
+ objectFit: 'cover',
2810
+ },
2811
+ titleRow: {
2812
+ width: '100%',
2813
+ marginTop: useResponsiveValue(theme.sizes.xxs, theme.sizes.xxxs, isDesktop, isTablet),
2814
+ marginBottom: useResponsiveValue(theme.sizes.xxs, theme.sizes.xxxs, isDesktop, isTablet),
2815
+ },
2816
+ titleText: {
2817
+ maxWidth: '90%',
2818
+ flex: 1,
2819
+ },
2820
+ progressContainer: {
2821
+ width: '100%',
2822
+ marginTop: useResponsiveValue(theme.sizes.xxs, theme.sizes.xxxs, isDesktop, isTablet),
2823
+ },
2824
+ });
2825
+ };
2826
+
2827
+ /**
2828
+ * Renders the media header for a Campaign Tile.
2829
+ *
2830
+ * @param props {CampaignTileMediaProps} - Component props
2831
+ * @param props.isArtworkOnly {boolean} - Whether the media should occupy the full tile height
2832
+ * @returns React.ReactElement or null if no artworkUrl is present
2833
+ */
2834
+ var CampaignTileMedia = function (_a) {
2835
+ var _b = _a.isArtworkOnly, isArtworkOnly = _b === void 0 ? false : _b;
2836
+ var styles = useCampaignTileStyles();
2837
+ var tileContext = useTileContext();
2838
+ if (!isContextValid(tileContext))
2839
+ return null;
2840
+ var _c = tileContext.configuration, artworkUrl = _c.artworkUrl, _d = _c.name, name = _d === void 0 ? 'Campaign' : _d;
2841
+ var containerStyle = isArtworkOnly
2842
+ ? {
2843
+ flexBasis: '100%',
2844
+ flex: 1,
2845
+ height: '100%',
2846
+ marginBottom: 0,
2847
+ minHeight: 0,
2848
+ aspectRatio: tileContext.tileHeight === exports.TileHeight.Half ? 2 : 1,
2849
+ }
2850
+ : __assign({ flexBasis: '50%' }, (tileContext.tileHeight === exports.TileHeight.Half && { minHeight: 0 }));
2851
+ return (jsxRuntimeExports.jsx(reactNative.View, { style: [styles.imageContainer, containerStyle], testID: "campaign-tile-media", role: "img", accessibilityLabel: "Campaign image for ".concat(name), children: jsxRuntimeExports.jsx(ProgressiveImage, { source: { uri: artworkUrl }, style: styles.image, alt: "Campaign image for ".concat(name) }) }));
2852
+ };
2853
+
2854
+ /**
2855
+ * Renders the progress bar and progress label for a Campaign Tile.
2856
+ * If progress is null, nothing is rendered.
2857
+ *
2858
+ * @param props - Component props
2859
+ * @param props.progress - The campaign progress data
2860
+ * @returns React.ReactElement or null if progress is null
2861
+ */
2862
+ var CampaignTileProgress = function (_a) {
2863
+ var progress = _a.progress;
2864
+ var styles = useCampaignTileStyles();
2865
+ if (!progress)
2866
+ return null;
2867
+ var currentValue = progress.currentValue, targetValue = progress.targetValue;
2868
+ var percentage = targetValue > 0 ? (currentValue / targetValue) * 100 : 0;
2869
+ return (jsxRuntimeExports.jsx(reactNative.View, { style: styles.progressContainer, testID: "campaign-tile-progress", children: jsxRuntimeExports.jsx(ProgressBar, { percentage: percentage, variant: "primary", height: "sm", currentValue: currentValue, targetValue: targetValue, showProgressLabel: true }) }));
2870
+ };
2871
+
2872
+ /**
2873
+ * Renders the title of a Campaign Tile.
2874
+ *
2875
+ * @returns React.ReactElement or null if no name is present
2876
+ */
2877
+ var CampaignTileTitle = function () {
2878
+ var tileContext = useTileContext();
2879
+ var styles = useCampaignTileStyles();
2880
+ if (!isContextValid(tileContext))
2881
+ return null;
2882
+ var name = tileContext.configuration.name;
2883
+ if (!name)
2884
+ return null;
2885
+ return (jsxRuntimeExports.jsx(Text, { variant: "title", ellipsizeMode: "tail", numberOfLines: 1, role: "heading", accessibilityLabel: "Campaign title: ".concat(name), testID: "campaign-tile-title", style: styles.titleText, children: name }));
2886
+ };
2887
+
2888
+ /**
2889
+ * Renders a chevron icon for a Campaign Tile.
2890
+ *
2891
+ * @returns React.ReactElement
2892
+ */
2893
+ var CampaignTileChevron = function () {
2894
+ var _a;
2895
+ var theme = useWllSdk().theme;
2896
+ 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 Campaign details" }));
2897
+ };
2898
+
2899
+ /**
2900
+ * Helper function to determine if the tile should display artwork only.
2901
+ *
2902
+ * @param configuration - The configuration object of the tile.
2903
+ * @returns `true` if the tile should display artwork only.
2904
+ */
2905
+ var isArtworkOnly$2 = function (configuration) {
2906
+ if (!configuration)
2907
+ return false;
2908
+ return !configuration.showDetails;
2909
+ };
2910
+ /**
2911
+ * The CampaignTile component renders a tile displaying campaign progress.
2912
+ * It shows a campaign image, title, description, and a progress bar
2913
+ * indicating the user's current progress towards the campaign goal.
2914
+ *
2915
+ * If progress is null, the progress bar is hidden completely.
2916
+ * If showDetails is false, only the artwork is displayed.
2917
+ *
2918
+ * @param {CampaignTileProps} props - Component props
2919
+ * @param {Tile} props.tile - The tile data to render
2920
+ * @returns React.ReactElement or null if tile is inactive or missing configuration
2921
+ */
2922
+ var CampaignTileRoot = function (_a) {
2923
+ var tile = _a.tile;
2924
+ var styles = useCampaignTileStyles();
2925
+ if (!tile || !tile.active || !tile.configuration)
2926
+ return null;
2927
+ var configuration = tile.configuration;
2928
+ var progress = configuration.progress;
2929
+ var artworkOnly = isArtworkOnly$2(configuration);
2930
+ return (jsxRuntimeExports.jsxs(BaseTile, { tile: tile, children: [jsxRuntimeExports.jsx(CampaignTile.Media, { isArtworkOnly: artworkOnly }), !artworkOnly && (jsxRuntimeExports.jsxs(Layout, { children: [jsxRuntimeExports.jsxs(Row, { justify: "between", align: "center", style: styles.titleRow, children: [jsxRuntimeExports.jsx(CampaignTile.Title, {}), jsxRuntimeExports.jsx(CampaignTile.Chevron, {})] }), jsxRuntimeExports.jsx(reactNative.View, { style: { width: '100%', maxWidth: '100%', minWidth: 0 }, children: jsxRuntimeExports.jsx(CampaignTile.Description, {}) }), jsxRuntimeExports.jsx(Row, { justify: "between", align: "center", style: styles.titleRow, children: jsxRuntimeExports.jsx(CampaignTile.Progress, { progress: progress }) })] }))] }));
2931
+ };
2932
+ /**
2933
+ * The CampaignTile component with subcomponents attached.
2934
+ */
2935
+ var CampaignTile = Object.assign(CampaignTileRoot, {
2936
+ Media: CampaignTileMedia,
2937
+ Title: CampaignTileTitle,
2938
+ Description: CampaignTileDescription,
2939
+ Progress: CampaignTileProgress,
2940
+ Chevron: CampaignTileChevron
2941
+ });
2942
+ var CampaignTile$1 = withTileFetching(CampaignTile);
2943
+
2714
2944
  var ContentTileChevron = function () {
2715
2945
  var _a, _b;
2716
2946
  var tileContext = useTileContext();
@@ -4751,6 +4981,7 @@ var TILE_COMPONENTS = (_a = {},
4751
4981
  _a[exports.TileType.Banner] = BannerTile$1,
4752
4982
  _a[exports.TileType.Roundup] = RoundupTile$1,
4753
4983
  _a[exports.TileType.Venue] = VenueTile$1,
4984
+ _a[exports.TileType.Campaign] = CampaignTile$1,
4754
4985
  _a);
4755
4986
  /**
4756
4987
  * TileContainer component to render a list of tiles with proper layout and spacing.
@@ -4875,6 +5106,8 @@ exports.BaseBanner = BaseBanner;
4875
5106
  exports.BaseTile = BaseTile;
4876
5107
  exports.Button = Button;
4877
5108
  exports.COLOR_CONSTANTS = COLOR_CONSTANTS;
5109
+ exports.CampaignTile = CampaignTile$1;
5110
+ exports.CampaignTileConfig = CampaignTileConfig;
4878
5111
  exports.Carousel = Carousel;
4879
5112
  exports.CarouselNavButton = CarouselNavButton;
4880
5113
  exports.Chip = Chip;