Padrão de design de componentes agnósticos

mggcmatheus

Matheus

Posted on October 8, 2024

Padrão de design de componentes agnósticos

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
Enter fullscreen mode Exit fullscreen mode

É 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';
}

Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

Utilização

Onde for utilizar, basta realizar a importação do componente agnóstico:

import Button from "@/shared/common/ui/components/Button/Button";
Enter fullscreen mode Exit fullscreen mode

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")}
/>
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
mggcmatheus
Matheus

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