Helena Strada |
Criar componentes no React Native é uma tarefa diária!
Nesse vídeo vamos utilizar o Styled-Components para criar nossos componentes utilizando props de maneira dinâmica, reutilizáveis e centralizadas para facilitar o desenvolvimento e manutenção do ciclo de vida da sua aplicação.
Esse projeto foi construído utilizando as seguintes tecnologias:
Para clonar o projeto, utilize os comandos:
# Clonar o repositório
❯ git clone https://github.com/rocketseat-experts-club/criando-componentes-styled-components-react-native-2021-02-27.git
# Acessar o repositório
❯ cd criando-componentes-styled-components-react-native-2021-02-27
IOS
# Entre na pasta do diretório
> cd template/Stylert
# Instale as dependências
❯ yarn
# Instale as referências do iOS
❯ npx pod-install ios
# Inicie o projeto
❯ yarn ios
Android
# Entre na pasta do diretório
> cd template/Stylert
# Instale as dependências
❯ yarn
# Inicie o projeto
❯ yarn android
Reaproveitamento de código, organização centralizada, manutenção.
Criação do Container
// src/components/Card/styles.tsx
import styled from "styled-components/native";
export const Container = styled.View`
height: 72px;
padding: 14px;
margin: 24px;
border-radius: 4px;
flex-direction: row;
justify-content: space-between;
align-items: center;
background-color: ${({ theme }) => theme.colors["neutral-100"]};
`;
Utilizando o Container
// src/components/Card/index.tsx
import { Container } from "./styles";
<Container>
<Text>Hello</Text>
<Text>Hello</Text>
</Container>;
- estilos centralizados;
- escopos locais, ou seja, sem efeitos colaterais dado que a alteração ocorre somente naquele ambiente;
- e algo muito massa, são estilos dinâmicos;
Criação da label e da descrição
// src/components/Card/styles.tsx
export const Label = styled.Text`
font-family: ${({ theme }) => theme.fonts.text};
font-size: 24px;
color: ${({ theme }) => theme.colors["neutral-700"]};
`;
export const Description = styled.Text`
font-family: ${({ theme }) => theme.fonts.text};
font-size: 24px;
color: ${({ theme }) => theme.colors["neutral-700"]};
`;
// src/components/Card/index.tsx
import { Container, Label, Description } from "./styles";
<Container>
<Label>R$ 100,00</Label>
<Description>pago</Description>
</Container>;
Criando um estilo compartilhado
// src/components/Card/styles.tsx
import styled, { css } from "styled-components/native";
const fontVariant = css`
font-family: ${({ theme }) => theme.fonts.text};
font-size: 24px;
color: ${({ theme }) => theme.colors["neutral-700"]};
`;
export const Label = styled.Text`
${fontVariant};
`;
export const Description = styled.Text`
${fontVariant};
`;
// src/components/Card/interface.ts
export enum CardStatus {
PAGO = "pago",
EM_ABERTO = "em aberto",
}
export interface ICardProps {
amount: string;
status: keyof typeof CardStatus;
}
// src/components/Card/index.tsx
import React from "react";
import { ICardProps } from "./interface";
import { Container, Label, Description } from "./styles";
const Card = ({ amount, status }: ICardProps) => {
return (
<Container>
<Label>{amount}</Label>
<Description>{CardStatus[status]}</Description>
</Container>
);
};
export default Card;
// src/components/App.tsx
<Card amount="R$ 100,00" status="PAGO" />
// src/components/Card/index.tsx
const Card = ({ amount, status }: ICardProps) => {
const isPaid = status === "PAGO" ? "success-400" : "warning-400";
return (
<Container>
<Label>{amount}</Label>
<Description color={isPaid}>{CardStatus[status]}</Description>
</Container>
);
};
// src/components/Card/interface.ts
import { colors } from "../../theme/colors";
export interface ICardStyledProps {
color: keyof typeof colors;
}
// src/components/Card/styles.tsx
export const Description =
styled.Text <
ICardStyledProps >
`
${fontVariant};
color: ${({ color, theme }) => theme.colors[color]};
`;
// src/App.tsx
<Card amount="R$ 100,00" status="PAGO" />
<Card amount="R$ 100,00" status="EM_ABERTO" />
// src/components/Card/index.tsx
import { ICardProps, CardStatus, TCardStatusVariant } from "./interface";
const Card = ({ amount, status }: ICardProps) => {
// const isPaid = status === "PAGO" ? "success-400" : "warning-400";
const statusVariant: TCardStatusVariant = {
PAGO: "success-400",
EM_ABERTO: "warning-400",
EM_ATRASO: "error-400",
REVERTIDO: "neutral-400",
};
return (
<Container>
<Label>{amount}</Label>
<Description color={statusVariant[status]}>
{CardStatus[status]}
</Description>
</Container>
);
};
Adicionar os itens a interface
// src/components/Card/interface.ts
export enum CardStatus {
PAGO = "pago",
EM_ABERTO = "em aberto",
EM_ATRASO = "em atraso",
REVERTIDO = "revertido",
}
export type TCardStatusVariant = {
[key in keyof typeof CardStatus]: keyof typeof colors;
};
// src/components/Card/index.tsx
import { ICardProps, CardStatus, TCardStatusVariant } from "./interface";
const Card = ({ amount, status }: ICardProps) => {
// const isPaid = status === "PAGO" ? "success-400" : "warning-400";
const isStatusReversed = status === "REVERTIDO";
const statusVariant: TCardStatusVariant = {
PAGO: "success-400",
EM_ABERTO: "warning-400",
EM_ATRASO: "error-400",
REVERTIDO: "neutral-400",
};
return (
<Container>
<Label>{amount}</Label>
<Description
strikeThrough={isStatusReversed}
color={statusVariant[status]}
>
{CardStatus[status]}
</Description>
</Container>
);
};
Adicionando a interface
// src/components/Card/interface.ts
export interface ICardStyledProps {
color: keyof typeof colors;
strikeThrough: boolean;
}
// src/components/Card/styles.tsx
${({ strikeThrough, theme, color }) =>
strikeThrough &&
css`
text-decoration: line-through;
text-decoration-color: ${theme.colors[color]};
`};