Refactor: Update component styles and JSON data for ESP32 series

- Added cursor pointer to buttons in SeriesTabMenu for better UX.
- Removed "Analog" category from various ESP32 JSON files to streamline categorization.
- Translated "analog" to "analógico" in ESP32 JSON files for consistency in language.
- Cleaned up categories in ESP32 JSON files to focus on relevant classifications.
This commit is contained in:
Lucas Rayan committed 2025-10-22 23:40:58 -03:00
1 parent 2a6699bbfb
commit 941dd266a0
12 files changed
+393 -103

No files matched your search

-4
View File
@@ -125,10 +125,6 @@ export default function Sobre() {
>
Ver repositório
</a>
<Link href="/contato" className="inline-flex items-center justify-center px-4 py-2 rounded-lg border border-gray-200 text-gray-700 hover:border-purple-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500" aria-label="Ir para a página de contato">
Entrar em contato
</Link>
</div>
<div className="mt-4 text-sm text-gray-500">
+2 -2
View File
@@ -86,7 +86,7 @@ export default function CodeExample({ framework }) {
<button
onClick={handleCopy}
className="inline-flex items-center gap-2 bg-white text-gray-800 px-3 py-2 rounded-lg font-medium shadow border-2 border-gray-100 hover:shadow-lg transition"
className="inline-flex items-center gap-2 bg-white text-gray-800 px-3 py-2 rounded-lg font-medium shadow border-2 border-gray-100 cursor-pointer hover:shadow-lg transition"
title="Copiar código"
>
{copied ? '✅ Copiado' : '📋 Copiar'}
@@ -111,7 +111,7 @@ export default function CodeExample({ framework }) {
<div className="rounded-lg overflow-hidden border">
<div className="p-0">
<div className="flex items-center justify-between bg-gradient-to-r from-gray-900 to-gray-800 p-3">
<div className="flex items-center justify-between bg-linear-to-r from-gray-900 to-gray-800 p-3">
<div className="text-xs text-gray-300 font-medium">{framework?.nome}</div>
<div className="text-xs text-gray-400">
{loading ? 'Carregando exemplo...' : (framework?.exemplo ? 'Exemplo do framework' : 'Abrir no GitHub')}
+353 -33
View File
@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect } from "react";
import { useState, useEffect, useMemo } from "react";
const FILTER_CATEGORIES = [
{ id: "All", name: "Todos", color: "#64748b" },
@@ -25,10 +25,16 @@ export default function ConnectionsDiagram({ connections, color }) {
const [activeFilter, setActiveFilter] = useState("All");
const [selectedConnection, setSelectedConnection] = useState(null);
const [hoveredConnection, setHoveredConnection] = useState(null);
const [searchQuery, setSearchQuery] = useState("");
const [viewMode, setViewMode] = useState("grid"); // 'grid' or 'list'
const [showTooltip, setShowTooltip] = useState(null);
const isConnectionVisible = (connection) => {
if (activeFilter === "All") return true;
return connection.categorias.includes(activeFilter);
const matchesFilter = activeFilter === "All" || connection.categorias.includes(activeFilter);
const matchesSearch = searchQuery === "" ||
connection.nome.toLowerCase().includes(searchQuery.toLowerCase()) ||
connection.numero.toString().toLowerCase().includes(searchQuery.toLowerCase());
return matchesFilter && matchesSearch;
};
const getCategoryColor = (category) => {
@@ -36,9 +42,23 @@ export default function ConnectionsDiagram({ connections, color }) {
return filter?.color || "#64748b";
};
const visibleConnections = useMemo(() => {
return connections.filter(isConnectionVisible);
}, [connections, activeFilter, searchQuery]);
const activeCategories = useMemo(() => {
if (activeFilter === "All") return [];
return FILTER_CATEGORIES.filter(cat =>
visibleConnections.some(conn => conn.categorias.includes(cat.id))
);
}, [visibleConnections, activeFilter]);
useEffect(() => {
const handleEscape = (e) => {
if (e.key === "Escape") setSelectedConnection(null);
if (e.key === "Escape") {
setSelectedConnection(null);
setShowTooltip(null);
}
};
if (selectedConnection) {
@@ -52,6 +72,28 @@ export default function ConnectionsDiagram({ connections, color }) {
};
}, [selectedConnection]);
useEffect(() => {
const handleKeyDown = (e) => {
if (selectedConnection) return;
if (e.key === "Tab") {
const buttons = document.querySelectorAll('[data-connection-button]');
const currentIndex = Array.from(buttons).findIndex(btn => btn === document.activeElement);
if (e.shiftKey && currentIndex > 0) {
e.preventDefault();
buttons[currentIndex - 1].focus();
} else if (!e.shiftKey && currentIndex < buttons.length - 1) {
e.preventDefault();
buttons[currentIndex + 1].focus();
}
}
};
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
}, [selectedConnection]);
if (!connections || connections.length === 0) {
return (
<div className="flex flex-col items-center justify-center py-16 px-4">
@@ -88,10 +130,80 @@ export default function ConnectionsDiagram({ connections, color }) {
Diagrama de Conexões Interativo
</h2>
<p className="text-lg text-gray-600 leading-relaxed max-w-3xl">
Clique em qualquer conexão para ver informações detalhadas ou use filtros para destacar funções específicas.
Explore as conexões do ESP32. Use a busca, filtros por função ou passe o mouse para ver detalhes rápidos.
</p>
</div>
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 p-6 space-y-4">
<div className="flex flex-col sm:flex-row gap-4">
<div className="flex-1 relative">
<svg
className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<input
type="text"
placeholder="Buscar por nome ou número da conexão..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="w-full pl-12 pr-4 py-3 rounded-xl border-2 border-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all outline-none text-gray-700"
aria-label="Search connections"
/>
{searchQuery && (
<button
onClick={() => setSearchQuery("")}
className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 transition-colors"
aria-label="Clear search"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
</svg>
</button>
)}
</div>
<div className="flex gap-2 bg-gray-100 rounded-xl p-1">
<button
onClick={() => setViewMode("grid")}
className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-all ${
viewMode === "grid"
? "bg-white shadow-sm text-gray-900"
: "text-gray-600 hover:text-gray-900"
}`}
aria-label="Grid view"
aria-pressed={viewMode === "grid"}
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path d="M5 3a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2V5a2 2 0 00-2-2H5zM5 11a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2v-2a2 2 0 00-2-2H5zM11 5a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V5zM11 13a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
</svg>
<span className="hidden sm:inline font-medium">Grade</span>
</button>
<button
onClick={() => setViewMode("list")}
className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-all ${
viewMode === "list"
? "bg-white shadow-sm text-gray-900"
: "text-gray-600 hover:text-gray-900"
}`}
aria-label="List view"
aria-pressed={viewMode === "list"}
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M3 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clipRule="evenodd" />
</svg>
<span className="hidden sm:inline font-medium">Lista</span>
</button>
</div>
</div>
</div>
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 p-6">
<div className="flex items-center gap-3 mb-4">
<svg
@@ -110,65 +222,120 @@ export default function ConnectionsDiagram({ connections, color }) {
Filtre por Função
</h4>
{activeFilter !== "All" && (
<span className="ml-auto text-sm text-gray-600">
{connections.filter(isConnectionVisible).length} de {connections.length} conexões
<span className="ml-auto text-sm font-medium text-gray-600 bg-gray-100 px-3 py-1 rounded-full">
{visibleConnections.length} de {connections.length}
</span>
)}
</div>
<div className="flex flex-wrap gap-2.5">
{FILTER_CATEGORIES.map((filter) => {
const isActive = activeFilter === filter.id;
const count = connections.filter(c =>
filter.id === "All" ? true : c.categorias.includes(filter.id)
).length;
return (
<button
key={filter.id}
onClick={() => setActiveFilter(filter.id)}
aria-pressed={isActive}
aria-label={`Filter by ${filter.name}`}
className={`px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 ${
className={`group relative px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 ${
isActive
? "shadow-lg transform scale-105 text-white"
: "bg-gray-50 text-gray-700 hover:bg-gray-100 hover:shadow-md"
}`}
style={{
backgroundColor: isActive ? filter.color : undefined,
focusRingColor: filter.color,
borderColor: isActive ? filter.color : undefined,
}}
>
<span className="flex items-center gap-2">
{filter.name}
<span className={`text-xs px-1.5 py-0.5 rounded-full ${
isActive ? "bg-white/20" : "bg-gray-200"
}`}>
{count}
</span>
</span>
</button>
);
})}
</div>
{activeFilter !== "All" && activeCategories.length > 0 && (
<div className="mt-6 pt-6 border-t border-gray-200">
<p className="text-sm font-medium text-gray-600 mb-3">Categorias visíveis:</p>
<div className="flex flex-wrap gap-2">
{activeCategories.map(cat => (
<span
key={cat.id}
className="inline-flex items-center gap-1.5 px-3 py-1 rounded-lg text-xs font-medium text-white shadow-sm"
style={{ backgroundColor: cat.color }}
>
<span className="w-1.5 h-1.5 rounded-full bg-white"></span>
{cat.name}
</span>
))}
</div>
</div>
)}
</div>
{visibleConnections.length === 0 ? (
<div className="bg-linear-to-br from-gray-50 to-gray-100 rounded-2xl p-12 border-2 border-dashed border-gray-300 text-center">
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-gray-200 flex items-center justify-center">
<svg className="w-8 h-8 text-gray-400" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" stroke="currentColor">
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<p className="text-lg font-semibold text-gray-700 mb-2">Nenhuma conexão encontrada</p>
<p className="text-sm text-gray-500">Tente ajustar os filtros ou termo de busca</p>
<button
onClick={() => {
setActiveFilter("All");
setSearchQuery("");
}}
className="mt-4 px-6 py-2 bg-gray-900 text-white rounded-xl hover:bg-gray-800 transition-colors font-medium"
>
Limpar filtros
</button>
</div>
) : viewMode === "grid" ? (
<div className="bg-linear-to-br from-gray-50 to-gray-100 rounded-2xl p-8 border-2 border-gray-200 shadow-inner">
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4">
{connections.map((connection, index) => {
const visible = isConnectionVisible(connection);
{visibleConnections.map((connection, index) => {
const isHovered = hoveredConnection === index;
const connectionId = `connection-${index}`;
return (
<div key={index} className="relative">
<button
key={index}
onClick={() => visible && setSelectedConnection(connection)}
onMouseEnter={() => visible && setHoveredConnection(index)}
onMouseLeave={() => setHoveredConnection(null)}
disabled={!visible}
id={connectionId}
data-connection-button
onClick={() => setSelectedConnection(connection)}
onMouseEnter={() => {
setHoveredConnection(index);
setShowTooltip(index);
}}
onMouseLeave={() => {
setHoveredConnection(null);
setShowTooltip(null);
}}
onFocus={() => setHoveredConnection(index)}
onBlur={() => setHoveredConnection(null)}
aria-label={`Connection ${connection.nome}, number ${connection.numero}`}
className={`relative flex flex-col items-center justify-center p-2 rounded-2xl border-2 transition-all duration-300 ${
visible
? "opacity-100 hover:scale-110 hover:shadow-2xl hover:z-10 cursor-pointer active:scale-95"
: "opacity-15 cursor-not-allowed grayscale"
}`}
aria-describedby={showTooltip === index ? `tooltip-${index}` : undefined}
className="relative w-full flex flex-col items-center justify-center p-3 rounded-2xl border-2 transition-all duration-300 opacity-100 hover:scale-110 hover:shadow-2xl hover:z-10 cursor-pointer active:scale-95 focus:outline-none focus:ring-4 focus:ring-offset-2"
style={{
backgroundColor: visible ? connection.cor + "15" : "#f3f4f615",
borderColor: visible ? (isHovered ? connection.cor : connection.cor + "60") : "#d1d5db",
backgroundColor: connection.cor + "15",
borderColor: isHovered ? connection.cor : connection.cor + "60",
transform: isHovered ? "translateY(-2px)" : undefined,
focusRingColor: connection.cor,
}}
>
<div
className="w-12 h-12 rounded-full flex items-center justify-center text-white font-bold text-sm mb-3 shadow-lg ring-2 ring-white"
className="w-14 h-14 rounded-full flex items-center justify-center text-white font-bold text-sm mb-3 shadow-lg ring-2 ring-white"
style={{ backgroundColor: connection.cor }}
>
{typeof connection.numero === "number"
@@ -176,13 +343,29 @@ export default function ConnectionsDiagram({ connections, color }) {
: connection.numero.substring(0, 4)}
</div>
<div className="text-xs font-bold text-center text-gray-900 leading-tight">
<div className="text-xs font-bold text-center text-gray-900 leading-tight mb-2">
{connection.nome}
</div>
<div className="flex flex-wrap gap-1 justify-center">
{connection.categorias.slice(0, 5).map((cat) => (
<span
key={cat}
className="w-1.5 h-1.5 rounded-full"
style={{ backgroundColor: getCategoryColor(cat) }}
title={cat}
/>
))}
{connection.categorias.length > 5 && (
<span className="text-[10px] text-gray-500 font-medium">
+{connection.categorias.length - 5}
</span>
)}
</div>
{connection.restricoes && (
<div
className="absolute -top-2 -right-2 bg-red-500 rounded-full p-1.5 shadow-lg"
className="absolute -top-2 -right-2 bg-red-500 rounded-full p-1.5 shadow-lg ring-2 ring-white"
aria-label="Has restrictions"
>
<svg
@@ -199,10 +382,116 @@ export default function ConnectionsDiagram({ connections, color }) {
</div>
)}
</button>
{showTooltip === index && (
<div
id={`tooltip-${index}`}
role="tooltip"
className="absolute z-50 bottom-full left-1/2 -translate-x-1/2 mb-2 p-3 bg-gray-900 text-white text-xs rounded-lg shadow-xl max-w-xs pointer-events-none animate-fadeIn"
style={{ minWidth: "200px" }}
>
<div className="font-bold mb-1">{connection.nome}</div>
<div className="text-gray-300 mb-2">{connection.numero}</div>
<div className="flex flex-wrap gap-1 mb-2">
{connection.categorias.map((cat) => (
<span
key={cat}
className="px-1.5 py-0.5 rounded text-[10px] font-medium"
style={{
backgroundColor: getCategoryColor(cat) + "40",
color: "#fff"
}}
>
{cat === "Strapping" ? "Inicialização" : cat}
</span>
))}
</div>
<div className="text-gray-400 text-[10px]">Clique para detalhes</div>
<div className="absolute top-full left-1/2 -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900"></div>
</div>
)}
</div>
);
})}
</div>
</div>
) : (
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-linear-to-r from-gray-50 to-gray-100 border-b-2 border-gray-200">
<tr>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Pin</th>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Nome</th>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Categorias</th>
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Funções</th>
<th className="px-6 py-4 text-center text-xs font-bold text-gray-700 uppercase tracking-wider">Status</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
{visibleConnections.map((connection, index) => (
<tr
key={index}
onClick={() => setSelectedConnection(connection)}
className="hover:bg-gray-50 cursor-pointer transition-colors group"
>
<td className="px-6 py-4 whitespace-nowrap">
<div
className="w-10 h-10 rounded-full flex items-center justify-center text-white font-bold text-sm shadow-md"
style={{ backgroundColor: connection.cor }}
>
{typeof connection.numero === "number"
? connection.numero
: connection.numero.substring(0, 4)}
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm font-bold text-gray-900 group-hover:text-blue-600 transition-colors">
{connection.nome}
</div>
</td>
<td className="px-6 py-4">
<div className="flex flex-wrap gap-1.5">
{connection.categorias.map((cat) => (
<span
key={cat}
className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium text-white"
style={{ backgroundColor: getCategoryColor(cat) }}
>
{cat === "Strapping" ? "Inicialização" : cat}
</span>
))}
</div>
</td>
<td className="px-6 py-4">
<div className="text-sm text-gray-600 max-w-md">
{connection.funcoes.join(", ")}
</div>
</td>
<td className="px-6 py-4 text-center">
{connection.restricoes ? (
<span className="inline-flex items-center gap-1 px-2 py-1 rounded-full bg-red-100 text-red-700 text-xs font-medium">
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
Atenção
</span>
) : (
<span className="inline-flex items-center gap-1 px-2 py-1 rounded-full bg-green-100 text-green-700 text-xs font-medium">
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
OK
</span>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
{connections.some(c => c.restricoes) && (
<div className="bg-linear-to-r from-amber-50 to-yellow-50 border-2 border-amber-200 rounded-2xl p-6 shadow-sm">
@@ -248,7 +537,7 @@ export default function ConnectionsDiagram({ connections, color }) {
{selectedConnection && (
<div
className="fixed inset-0 bg-opacity-80 backdrop-blur-xs flex items-center justify-center p-4 z-50 animate-fadeIn h-full"
className="fixed inset-0 bg-black bg-opacity-80 backdrop-blur-sm flex items-center justify-center p-4 z-50 animate-fadeIn"
onClick={() => setSelectedConnection(null)}
role="dialog"
aria-modal="true"
@@ -258,7 +547,7 @@ export default function ConnectionsDiagram({ connections, color }) {
className="bg-white rounded-3xl shadow-2xl max-w-3xl w-full max-h-[90vh] overflow-hidden flex flex-col animate-slideUp"
onClick={(e) => e.stopPropagation()}
>
<div className="sticky top-0 bg-linear-to-r from-white to-gray-50 border-b-2 border-gray-200 p-8">
<div className="sticky top-0 bg-linear-to-r from-white to-gray-50 border-b-2 border-gray-200 p-8 z-10">
<div className="flex items-start justify-between gap-6">
<div className="flex items-center gap-5 flex-1">
<div
@@ -314,7 +603,9 @@ export default function ConnectionsDiagram({ connections, color }) {
key={cat}
className="px-4 py-2 rounded-xl text-sm font-bold text-white shadow-md ring-2 ring-white"
style={{ backgroundColor: getCategoryColor(cat) }}
>{cat}</span>
>
{cat === "Strapping" ? "Inicialização" : cat}
</span>
))}
</div>
</div>
@@ -380,7 +671,7 @@ export default function ConnectionsDiagram({ connections, color }) {
style={{ backgroundColor: color }}
aria-label="Close modal"
>
Close
Fechar
</button>
</div>
</div>
@@ -388,7 +679,12 @@ export default function ConnectionsDiagram({ connections, color }) {
)}
<div className="bg-white rounded-2xl shadow-lg p-6 border-2 border-gray-100">
<h3 className="text-lg font-bold text-gray-800 mb-3">Sobre a Matriz de Conexões Flexível</h3>
<h3 className="text-lg font-bold text-gray-800 mb-3 flex items-center gap-2">
<svg className="w-5 h-5 text-blue-600" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
</svg>
Sobre a Matriz de Conexões Flexível
</h3>
<p className="text-gray-700 leading-relaxed">
O ESP32 possui uma matriz de conexões flexível que permite mapear diversas funções para múltiplos pinos.
Isso significa que muitas conexões podem ser configuradas para desempenhar diferentes papéis, dependendo das necessidades do seu projeto.
@@ -424,6 +720,30 @@ export default function ConnectionsDiagram({ connections, color }) {
.animate-slideUp {
animation: slideUp 0.3s ease-out;
}
/* Smooth scroll for modal */
.overflow-y-auto {
scrollbar-width: thin;
scrollbar-color: #cbd5e0 #f7fafc;
}
.overflow-y-auto::-webkit-scrollbar {
width: 8px;
}
.overflow-y-auto::-webkit-scrollbar-track {
background: #f7fafc;
border-radius: 10px;
}
.overflow-y-auto::-webkit-scrollbar-thumb {
background: #cbd5e0;
border-radius: 10px;
}
.overflow-y-auto::-webkit-scrollbar-thumb:hover {
background: #a0aec0;
}
`}</style>
</div>
);
+1 -1
View File
@@ -15,7 +15,7 @@ export default function SeriesTabMenu({ tabs, color }) {
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`flex-1 flex items-center justify-center gap-2 py-4 px-6 rounded-xl font-semibold transition-all duration-300 ${
className={`flex-1 flex items-center justify-center gap-2 py-4 px-6 rounded-xl font-semibold transition-all duration-300 cursor-pointer ${
activeTab === tab.id
? 'text-white shadow-lg transform scale-105'
: 'text-gray-600 hover:bg-gray-50'
+4 -8
View File
@@ -34,8 +34,7 @@
"Alimentação do domínio analógico"
],
"categorias": [
"Power",
"Analog"
"Power"
],
"cor": "#ef4444",
"restricoes": "Opera entre 3.0 V e 3.6 V (típico 3.3 V)"
@@ -450,13 +449,12 @@
{
"numero": "XTAL_N",
"nome": "XTAL_N",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -465,13 +463,12 @@
{
"numero": "XTAL_P",
"nome": "XTAL_P",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -480,12 +477,11 @@
{
"numero": "LNA",
"nome": "LNA_IN",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída do amplificador de baixo ruído RF"
],
"categorias": [
"Analog",
"RF"
],
"cor": "#a855f7",
+5 -12
View File
@@ -21,8 +21,7 @@
"Alimentação do domínio analógico"
],
"categorias": [
"Power",
"Analog"
"Power"
],
"cor": "#ef4444",
"restricoes": "Opera entre 3.0 V e 3.6 V (típico 3.3 V)"
@@ -281,7 +280,6 @@
"categorias": [
"GPIO",
"SDIO",
"Analog",
"Strapping"
],
"cor": "#3b82f6",
@@ -299,7 +297,6 @@
"categorias": [
"GPIO",
"SDIO",
"Analog",
"Strapping"
],
"cor": "#3b82f6",
@@ -591,13 +588,12 @@
{
"numero": "XTAL_N",
"nome": "XTAL_N",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -606,13 +602,12 @@
{
"numero": "XTAL_P",
"nome": "XTAL_P",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -621,12 +616,11 @@
{
"numero": "ANT",
"nome": "ANT_2G",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de RF 2.4 GHz"
],
"categorias": [
"Analog",
"RF"
],
"cor": "#a855f7",
@@ -635,12 +629,11 @@
{
"numero": "ANT",
"nome": "ANT_5G",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de RF 5 GHz"
],
"categorias": [
"Analog",
"RF"
],
"cor": "#a855f7",
+4 -8
View File
@@ -21,8 +21,7 @@
"Alimentação do domínio analógico"
],
"categorias": [
"Power",
"Analog"
"Power"
],
"cor": "#ef4444",
"restricoes": "Opera entre 3.0 V e 3.6 V (típico 3.3 V)"
@@ -607,13 +606,12 @@
{
"numero": "XTAL_N",
"nome": "XTAL_N",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -622,13 +620,12 @@
{
"numero": "XTAL_P",
"nome": "XTAL_P",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -637,13 +634,12 @@
{
"numero": "ANT",
"nome": "ANT",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída RF para comunicação 2.4 GHz",
"Interface de antena Wi-Fi/BLE/802.15.4"
],
"categorias": [
"Analog",
"RF"
],
"cor": "#a855f7",
+6 -12
View File
@@ -36,8 +36,7 @@
"Alimentação para pinos GPIO12, XTAL32KP, XTAL32KN"
],
"categorias": [
"Power",
"Analog"
"Power"
],
"cor": "#ef4444",
"restricoes": "Opera entre 3.0 V e 3.6 V (típico 3.3 V)"
@@ -243,8 +242,7 @@
"Voltage Comparator ZCD0"
],
"categorias": [
"GPIO",
"Analog"
"GPIO"
],
"cor": "#3b82f6",
"restricoes": ""
@@ -258,8 +256,7 @@
"Voltage Comparator ZCD1"
],
"categorias": [
"GPIO",
"Analog"
"GPIO"
],
"cor": "#3b82f6",
"restricoes": ""
@@ -409,13 +406,12 @@
{
"numero": "XTAL_N",
"nome": "XTAL_N",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -424,13 +420,12 @@
{
"numero": "XTAL_P",
"nome": "XTAL_P",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -439,13 +434,12 @@
{
"numero": "ANT",
"nome": "ANT",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída RF para comunicação sem fio",
"Amplificador de baixo ruído RF"
],
"categorias": [
"Analog",
"RF"
],
"cor": "#a855f7",
+12 -12
View File
@@ -845,7 +845,7 @@
"ANACOMP0_P",
"EMAC_RX_DV"
],
"categorias": ["GPIO", "ADC", "Analog", "Ethernet"],
"categorias": ["GPIO", "ADC", "Ethernet"],
"cor": "#3b82f6",
"restricoes": ""
},
@@ -859,7 +859,7 @@
"ANACOMP0_N",
"EMAC_RXD0"
],
"categorias": ["GPIO", "ADC", "Analog", "Ethernet"],
"categorias": ["GPIO", "ADC", "Ethernet"],
"cor": "#3b82f6",
"restricoes": ""
},
@@ -873,7 +873,7 @@
"ANACOMP1_P",
"EMAC_RXD1"
],
"categorias": ["GPIO", "ADC", "Analog", "Ethernet"],
"categorias": ["GPIO", "ADC", "Ethernet"],
"cor": "#3b82f6",
"restricoes": ""
},
@@ -887,7 +887,7 @@
"ANACOMP1_N",
"EMAC_RX_ER"
],
"categorias": ["GPIO", "ADC", "Analog", "Ethernet"],
"categorias": ["GPIO", "ADC", "Ethernet"],
"cor": "#3b82f6",
"restricoes": ""
},
@@ -982,47 +982,47 @@
{
"numero": "XTAL_N",
"nome": "XTAL_N",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": ["Analog", "Clock"],
"categorias": ["Clock"],
"cor": "#a855f7",
"restricoes": "Clock diferencial negativo"
},
{
"numero": "XTAL_P",
"nome": "XTAL_P",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": ["Analog", "Clock"],
"categorias": ["Clock"],
"cor": "#a855f7",
"restricoes": "Clock diferencial positivo"
},
{
"numero": "FBDCDC",
"nome": "FB_DCDC",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Feedback de alimentação para DCDC externo",
"Regula tensão de VDDHP0/2/3"
],
"categorias": ["Analog", "Power"],
"categorias": ["Power"],
"cor": "#a855f7",
"restricoes": ""
},
{
"numero": "ENDCDC",
"nome": "EN_DCDC",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Enable pin para DCDC externo"
],
"categorias": ["Analog", "Power"],
"categorias": ["Power"],
"cor": "#a855f7",
"restricoes": ""
}
+1 -2
View File
@@ -21,8 +21,7 @@
"Alimentação analógica do chip"
],
"categorias": [
"Power",
"Analog"
"Power"
],
"cor": "#ef4444",
"restricoes": "Opera entre 2.8 V e 3.6 V"
+4 -8
View File
@@ -34,8 +34,7 @@
"Alimentação do domínio analógico"
],
"categorias": [
"Power",
"Analog"
"Power"
],
"cor": "#ef4444",
"restricoes": "Opera entre 3.0 V e 3.6 V (típico 3.3 V)"
@@ -901,13 +900,12 @@
{
"numero": "XTAL_N",
"nome": "XTAL_N",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -916,13 +914,12 @@
{
"numero": "XTAL_P",
"nome": "XTAL_P",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída de clock externo",
"Conexão ao cristal ou oscilador do chip"
],
"categorias": [
"Analog",
"Clock"
],
"cor": "#a855f7",
@@ -931,12 +928,11 @@
{
"numero": "LNA",
"nome": "LNA_IN",
"tipo": "analog",
"tipo": "analógico",
"funcoes": [
"Entrada/saída do amplificador de baixo ruído RF"
],
"categorias": [
"Analog",
"RF"
],
"cor": "#a855f7",
+1 -1
View File
@@ -40,7 +40,7 @@
"nome": "VDDA",
"tipo": "power",
"funcoes": ["Alimentação analógica do chip", "Alimentação de referência para o ADC"],
"categorias": ["Power", "Analog"],
"categorias": ["Power"],
"cor": "#ef4444",
"restricoes": "Opera entre 3.0 V e 3.6 V com flash; entre 2.3 V e 3.6 V sem flash"
},