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.
Top comments (0)