I have a component that displays numbers from an array. I style these numbers with styled components. However, I want to make it so that if the numbers are below or equal to a variable(filled: number) change the colour to make it looked filled in. So if filled === 5, all numbers from 1-5 are filled in. Here is my code:
export interface ILoyaltyStatusProps {
filled: number;
orderCount: {
orderNumber: number;
}[];
statusTier: string;
points: number;
}
export const LoyaltyStatus: React.FC<ILoyaltyStatusProps> = ({
filled,
orderCount,
statusTier,
points,
...props
}) => {
const displayOrders = () =>
orderCount.map((ORDERS) => (
<OrderTextContainer>
<OrderText>{ORDERS.orderNumber}</OrderText>
</OrderTextContainer>
));
return (
// eslint-disable-next-line react/jsx-props-no-spreading
<Container {...props}>
<InnerContainer>
<MainContentContainer>
<TitleText>{`Unlock ${statusTier} Status`}</TitleText>
<SubText>{`Just order ${orderCount.length} times this month.`}</SubText>
<OrderContainer>{displayOrders()}</OrderContainer>
</MainContentContainer>
<FooterContentContainer>
<PointsText>
{`You'll earn ${points} points per dollar when you unlock ${statusTier} Status.`}
</PointsText>
</FooterContentContainer>
</InnerContainer>
<IconContainer>
<LockIcon />
</IconContainer>
</Container>
);
};
Here is the styling:
const OrderContainer = styled.View`
flex-direction: row;
flex-wrap: wrap;
flex-grow: 1;
padding: 10px;
justify-content: center;
background: ${({theme}) => theme.colors.background}};
`;
const OrderTextContainer = styled.View`
flex-direction: column;
flex-grow: 0;
flex-shrink: 1;
padding: 10px;
background: ${({theme}) => theme.colors.background}};
`;
const OrderText = styled(Text).attrs(() => ({
type: TextTypes.H4,
}))`
border: ${({theme}) => theme.colors.lightGreyBackground}};
background: ${({theme}) => theme.colors.background}};
color: ${({theme}) => theme.colors.text};
text-align: center;
padding-top: 5px;
width: 35px;
height: 35px;
border-radius: 999px;
border-width: 3px;
`;
I am using storybook to populate the data and the component looks like this: picture of my component
Here is my storybook file:
import {LoyaltyStatus} from '@molecules/LoyaltyStatus';
import {storiesOf} from '@storybook/react-native';
import React from 'react';
const dummy = [
{id: 1},
{id: 2},
{id: 3},
{id: 4},
{id: 1},
{id: 2},
{id: 3},
{id: 4},
{id: 4},
];
storiesOf('Loyalty Status', module).add('Default', () => (
<LoyaltyStatus
statusTier="Gold"
points={10}
orderCount={dummy.map((order) => ({
orderNumber: order.id,
}))}
/>
));
Basically, I just need to fill in all numbers preceding and including the filled variables to make them show as they have been redeemed. Does anybody know how you would do this in React-native typescript?
Edit: I eventually found a solution to my problem, however it was done by overlaying a new circle over the old one using absolute position like a stamp.
const displayOrders = () =>
orderCount.map((ORDERS) => (
<OrderTextContainer>
<OrderText>{ORDERS.orderNumber}</OrderText>
{ORDERS.orderNumber <= filled && (
<FilledOrderText>STAMPED</FilledOrderText>
)}
</OrderTextContainer>
));
Referring to documentation of styled components I would try to do next.
Update your function which mapping your orders like that:
const displayOrders = () =>
orderCount.map((ORDERS) => (
<OrderTextContainer>
<OrderText filled={ORDERS.orderNumber === filled}>
{ORDERS.orderNumber}
</OrderText>
</OrderTextContainer>
));
And then update your styling like that:
const OrderText = styled(Text).attrs(() => ({
type: TextTypes.H4,
}))`
border: ${({theme}) => theme.colors.lightGreyBackground}};
background: ${({filled}) => filled ? filledColor : regularColor}};
color: ${({theme}) => theme.colors.text};
text-align: center;
padding-top: 5px;
width: 35px;
height: 35px;
border-radius: 999px;
border-width: 3px;
`;
But I don't have any idea what styles you want to change so background is just an example.
Hope I could help you.
P.S: this solution written without typescript so be sure to add it by yourself :)