Padrão de design de componentes agnósticos
Matheus
Posted on October 8, 2024
Esse padrão visa criar componentes desacoplados de bibliotecas específicas, definindo uma camada de abstração que permite a
integração com diferentes frameworks ou bibliotecas de UI, como React, Vue, ou Angular, ou mesmo diferentes bibliotecas de UI dentro de um mesmo framework, como PrimeReact, Material-UI, etc.
Requisitos
Para aplicar este padrão, não é necessário definir todos os componentes de uma vez, o processo pode ser progressivo, sendo aplicado, conforme a necessidade de utilização de novos componentes.
Organização de pastas e arquivos
Por prefêrencia pessoal, costumo disponibilizar os componentes agnósticos, na camada de UI compartilhada para aplicação,
geralmente é a camada, onde ficam os types
, interfaces
, styles
, layouts
, e utils
.
Uma forma de organização de pastas, aplicando os conceitos de camadas, pode ser como a sugerida abaixo:
── src
└── shared
└── common
└── ui
└── components
└── Button
├── Button.interface.ts
├── Button.tsx
└── PrimeReactButton.component.tsx
É uma forma de organizar os componentes de forma que fique explícito que são compartilhados para aplicação inteira.
Implementação
Explicação sobre cada arquivo e como serem utilizados.
Button.interface.ts
- Este arquivo define a interface TypeScript para o componente Button.
Ele descreve os tipos das propriedades (props) que o componente Button aceita.
A interface ajuda a garantir que o uso do componente seja seguro e consistente,
facilitando a tipagem forte no TypeScript.
export interface ButtonPropsInterface {
label: string;
onClick: () => void;
disabled?: boolean;
type?: 'button' | 'submit' | 'reset';
}
Button.tsx
- Este arquivo contém a implementação genérica do componente Button em React.
Ele representa um botão "agnóstico", e atua como um wrapper que incorpora a lógica do botão e delega a renderização a um
adaptador,
que neste caso é o PrimeReactButtonComponent
.
import React from "react";
import { ButtonPropsInterface } from "@/shared/common/ui/components/Button/Button.interface";
import PrimeReactButtonComponent from "@/shared/common/ui/components/Button/PrimeReactButton.component";
const Button: React.FC<ButtonPropsInterface> = ({label, onClick, disabled, type = 'button'}) => {
return (
<PrimeReactButtonComponent type={type} onClick={onClick} disabled={disabled}>
{label}
</PrimeReactButtonComponent>
);
};
export default Button;
PrimeReactButton.component.tsx
- Este arquivo contém a implementação específica do componente Button
utilizando a
biblioteca PrimeReact
. Ele serve como um adaptador que adapta a interface genérica do botão para usar o componente específico do PrimeReact, mantendo a mesma interface definida no arquivo Button.interface.ts
. Assim, ele traduz as propriedades genéricas para a implementação específica da biblioteca.
import { ButtonProps } from './Button.interface';
import { Button as PrimeButton } from 'primereact/button';
const PrimeReactButtonComponent: React.FC<ButtonProps> = ({label, onClick, disabled, type = 'button'}) => {
return (
<PrimeButton label={label} onClick={onClick} disabled={disabled} type={type}/>
);
};
export default PrimeReactButtonComponent;
Utilização
Onde for utilizar, basta realizar a importação do componente agnóstico:
import Button from "@/shared/common/ui/components/Button/Button";
E realizar o uso normalmente, passando as propriedades obrigatórias e opcionais, caso desejado:
<Button
label="Voltar"
icon="pi pi-angle-left"
severity="secondary"
onClick={() => router.push("/home")}
/>
Troca de bibliotecas
Se for necessário um dia trocar a biblioteca, basta criar um adaptador que realize a implementação especifica da biblioteca,
e trocar na implementação genérica do componente pelo adaptador novo.
Posted on October 8, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
July 28, 2024