Skip to content

Commit

Permalink
Formalise pattern and add BadgeTile and ContentTile
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgraeme committed Sep 5, 2024
1 parent db36922 commit c53c100
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 75 deletions.
49 changes: 37 additions & 12 deletions lib/components/atoms/BaseTile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React, { createContext, FC, ReactNode, useContext } from 'react';
import { StyleSheet, View, Image, ImageProps } from 'react-native';
import Color from 'color';
import { Icon, Text } from '../../atoms';
import { FlexStyle, Image, StyleSheet, View, ViewStyle } from 'react-native';
import { useTheme } from '../../../context/ThemeContext';
import { ImagePropsNoSource } from '../../../types/common';
import { Tile, TileConfig, TileHeight } from '../../../types/tile';
import { createResponsiveStyle } from '../../../utils/responsiveHelper';
import { Icon, Text } from '../../atoms';
import { useSectionContext } from '../../organisms/Section';
import LoadingIndicator from '../LoadingIndicator';
import { createResponsiveStyle } from '../../../utils/responsiveHelper';
import { Tile, TileConfig } from '../../../types/tile';
import { ImagePropsNoSource } from '../../../types/common';

const TileContext = createContext<Tile | null>(null);

Expand All @@ -22,6 +21,7 @@ export const useTileContext = () => {
type BaseTileProps = {
tile: Tile;
children: ReactNode;
style?: ViewStyle;
};

type BaseTileComponent = FC<BaseTileProps> & {
Expand All @@ -30,10 +30,22 @@ type BaseTileComponent = FC<BaseTileProps> & {
Image: FC<ImagePropsNoSource>;
};

const BaseTileInner: FC<BaseTileProps> = ({ tile, children }) => {
type LayoutProps = FlexStyle & {
justifyContent?: 'flex-start' | 'center' | 'flex-end' | 'space-between';
};

const BaseTileInner: FC<BaseTileProps> = ({ tile, children, style }) => {
const { loading: isLoading } = useSectionContext();
const { theme } = useTheme();

const layout: LayoutProps = {
flexDirection: 'column',
justifyContent:
tile.tileHeight === TileHeight.Half || !tile.configuration.imageUrl
? 'center'
: 'flex-start',
alignItems: 'stretch',
};
const responsiveStyles = createResponsiveStyle({
borderRadius: [
theme.sizes.borderRadiusSm,
Expand All @@ -53,6 +65,8 @@ const BaseTileInner: FC<BaseTileProps> = ({ tile, children }) => {
borderRadius: responsiveStyles.borderRadius,
maxWidth: responsiveStyles.maxWidth,
},
layout,
style,
]}
>
{isLoading ? <LoadingIndicator /> : children}
Expand All @@ -64,22 +78,35 @@ const BaseTileInner: FC<BaseTileProps> = ({ tile, children }) => {
const TileTitle: FC = () => {
const tile = useTileContext();
const { theme } = useTheme();
const { title, linkURL } = tile.configuration as TileConfig & {
const { title, imageUrl, linkURL } = tile.configuration as TileConfig & {
title?: string;
linkURL?: string;
imageUrl?: string;
};

const titleContainerStyle = createResponsiveStyle({
marginTop: [8, 8, 12],
});

if (!title) return null;

return (
<View style={styles.titleContainer} accessibilityRole="header">
<View
style={[
styles.titleContainer,
{
marginTop: imageUrl ? titleContainerStyle.marginTop : undefined,
},
]}
accessibilityRole="header"
>
<Text variant="title" accessibilityLabel={title}>
{title}
</Text>
{linkURL && (
<Icon
name="ChevronRight"
size={16}
size={24}
color={theme.derivedSurfaceText[20]}
/>
)}
Expand Down Expand Up @@ -132,8 +159,6 @@ const styles = StyleSheet.create({
width: '100%',
height: '100%',
overflow: 'hidden',
alignItems: 'stretch',
justifyContent: 'flex-start',
position: 'relative',
aspectRatio: 1,
},
Expand Down
2 changes: 1 addition & 1 deletion lib/components/atoms/Text/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const Text: React.FC<TextProps> = ({
case 'body':
return createResponsiveStyle({
color: theme.derivedSurfaceText[20],
fontSize: 10,
fontSize: [10, 10, 14],
});
case 'caption':
return createResponsiveStyle({
Expand Down
44 changes: 9 additions & 35 deletions lib/components/atoms/TileContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
TierTileConfig,
Tile,
TileType,
} from "../../../types/tile";
import { useResponsiveScale } from "../../../utils/responsiveScaling";
} from '../../../types/tile';
import { useResponsiveScale } from '../../../utils/responsiveScaling';
import {
BadgeTile,
BannerTile,
Expand All @@ -18,52 +18,26 @@ import {
RewardCategoryTile,
RewardTile,
TierTile,
} from "../../organisms";
} from '../../organisms';

import React from "react";
import { StyleSheet, View } from "react-native";
import React from 'react';
import { StyleSheet, View } from 'react-native';

type TileContainerProps = {
tiles: Tile[];
};

const TileContainer: React.FC<TileContainerProps> = ({ tiles }) => {
const { ps, ms } = useResponsiveScale();
const { ms } = useResponsiveScale();

const renderTile = (tile: Tile) => {
switch (tile.type) {
case TileType.Banner: {
const config = tile.configuration as BannerTileConfig;
return <BannerTile configuration={config} />;
}
case TileType.Points: {
const config = tile.configuration as PointsTileConfig;
return <PointsTile configuration={config} />;
}
case TileType.Content: {
const config = tile.configuration as ContentTileConfig;
return <ContentTile configuration={config} />;
}
case TileType.Reward: {
const config = tile.configuration as RewardTileConfig;
// @ts-ignore
return <RewardTile configuration={config} />;
return <ContentTile tile={tile} />;
}
case TileType.Badge: {
const config = tile.configuration as BadgeTileConfig;
return <BadgeTile configuration={config} />;
}
case TileType.RewardCategory: {
const config = tile.configuration as RewardCategoryTileConfig;
// @ts-ignore we know this is wrong for the time being.
return <RewardCategoryTile configuration={config} />;
}
case TileType.Tier: {
const config = tile.configuration as TierTileConfig;
return <TierTile configuration={config} />;
return <BadgeTile tile={tile} />;
}
default:
throw new Error(`Unsupported tile type: ${tile.type}`);
}
};

Expand All @@ -88,7 +62,7 @@ const TileContainer: React.FC<TileContainerProps> = ({ tiles }) => {

const styles = StyleSheet.create({
container: {
flexDirection: "column",
flexDirection: 'column',
aspectRatio: 1,
},
tileContainer: {
Expand Down
6 changes: 3 additions & 3 deletions lib/components/organisms/BadgeTile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ const BadgeTileInner: FC<BadgeTileProps> = ({ tile }) => {
const BadgeTileImage: FC<ImagePropsNoSource> = (props) => {
const tile = useTileContext();
const { badge } = tile.configuration as TileConfig & { badge?: Badge };
if (!badge) return null;
if (!badge?.artworkUrl) return null;
return <Image {...props} source={{ uri: badge.artworkUrl }} />;
};

const BadgeTileTitle: FC = (props) => {
const tile = useTileContext();
const { badge } = tile.configuration as TileConfig & { badge?: Badge };
if (!badge) return null;
if (!badge?.name) return null;
return (
<Text variant="title" {...props}>
{badge.name}
Expand All @@ -59,7 +59,7 @@ const BadgeTileTitle: FC = (props) => {
const BadgeTileBody: FC = (props) => {
const tile = useTileContext();
const { badge } = tile.configuration as TileConfig & { badge?: Badge };
if (!badge) return null;
if (!badge?.description) return null;
return (
<Text variant="body" {...props}>
{badge.description}
Expand Down
Loading

0 comments on commit c53c100

Please sign in to comment.