css - Hur man ändrar egenskaperna hos en stylad textkomponent dynamiskt som visas inom en array?


Jag har en komponent som visar siffror från en array. Jag stilar dessa siffror med styled components. Men jag vill göra det så att om siffrorna är mindre än eller lika med en variabel (filled: number) ändras färgen för att det ska se fyllt ut. Så om filled === 5, är alla siffror från 1-5 fyllda. Här är min kod:

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>
  );
};

Här är stilen:

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;
`;

Jag använder Storybook för att fylla på datan och komponenten ser ut så här: bild på min komponent

Här är min sagoboksfil:

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,
    }))}
  />
));

I princip behöver jag bara fylla i alla nummer före och inklusive de ifyllda variablerna för att visa att de har lösts in. Vet någon hur man skulle göra detta i React-native typescript?


Redigera: Jag hittade till slut en lösning på mitt problem, men det gjordes genom att lägga ett nytt cirkel ovanpå den gamla med absolut positionering som ett frimärke.

const displayOrders = () =>
    orderCount.map((ORDERS) => (
      <OrderTextContainer>
        <OrderText>{ORDERS.orderNumber}</OrderText>
        {ORDERS.orderNumber <= filled && (
          <FilledOrderText>STAMPED</FilledOrderText>
        )}
      </OrderTextContainer>
    ));

Svar #1

Med hänvisning till dokumentationen av styled components skulle jag försöka göra nästa.

Uppdatera din funktion som kartlägger dina beställningar på det här sättet:

const displayOrders = () =>
    orderCount.map((ORDERS) => (
      <OrderTextContainer>
        <OrderText filled={ORDERS.orderNumber === filled}>
           {ORDERS.orderNumber}
        </OrderText>
      </OrderTextContainer>
    )); 

Och uppdatera sedan din styling på det sättet:

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;
`;

Men jag har ingen aning om vilka stilar du vill ändra, så bakgrunden är bara ett exempel.

Hoppas jag kunde hjälpa dig.

P.S: den här lösningen är skriven utan TypeScript så se till att lägga till det själv :)

Relaterade artiklar