Especialização Frontend com React & TypeScript • Demonstrações Práticas Executáveis


🎯 Contexto e Objetivo Prático

Demonstração de composição de componentes funcionais com Props tipadas, children polimórfico e callbacks fortemente tipados.


💻 Código Fonte React 19 (TSX)

// MetricCard.tsx
import React from "react";

export interface MetricCardProps {
  title: string;
  value: string | number;
  variationPercentage?: number;
  badgeText?: string;
  onRefresh?: (metricTitle: string) => void;
  children?: React.ReactNode;
}

export function MetricCard({
  title,
  value,
  variationPercentage,
  badgeText,
  onRefresh,
  children
}: MetricCardProps) {
  const isPositive = (variationPercentage ?? 0) >= 0;

  return (
    <article className="border border-slate-200 p-4 rounded-xl shadow-sm bg-white">
      <div className="flex items-center justify-between mb-2">
        <h3 className="text-sm font-semibold text-slate-600">{title}</h3>
        {badgeText && (
          <span className="text-xs font-mono bg-blue-50 text-blue-700 px-2 py-0.5 rounded">
            {badgeText}
          </span>
        )}
      </div>

      <div className="text-3xl font-extrabold text-slate-900 mb-2">{value}</div>

      {variationPercentage !== undefined && (
        <p className={`text-xs font-medium ${isPositive ? "text-emerald-600" : "text-rose-600"}`}>
          {isPositive ? "▲ +" : "▼ "}
          {variationPercentage.toFixed(1)}% em relação ao mês anterior
        </p>
      )}

      {children && <div className="mt-3 pt-3 border-t border-slate-100">{children}</div>}

      {onRefresh && (
        <button
          type="button"
          onClick={() => onRefresh(title)}
          className="mt-3 text-xs text-indigo-600 hover:text-indigo-800 font-semibold"
        >
          ↻ Atualizar métrica
        </button>
      )}
    </article>
  );
}

🖥️ Saída de Renderização Visual e Comportamento

[Componente MetricCard Renderizado]
Receita Recorrente Mensal (MRR)       [PRODUÇÃO]
R$ 148.500,00
▲ +12.4% em relação ao mês anterior
[↻ Atualizar métrica]