Concorde
BETA

ServiceCenterIcon

Icono de centro de servicio (chat + ?) para la navegación lateral del sidebar.

<ServiceCenterIcon size={32} state="default" />
<ServiceCenterIcon size={32} state="hover" />
<ServiceCenterIcon size={32} state="active" />

Instalación

$ npx github:AaronCoorahua/ConcordeV2#cli add servicecentericon

Uso

import ServiceCenterIcon from "@/src/components/ServiceCenterIcon";

// Autónomo — trackea hover/active solo
<ServiceCenterIcon size={24} />

// Controlado — el padre pasa el estado
<ServiceCenterIcon size={24} state="hover" />

Ejemplos

Estados

Default (gradiente púrpura diagonal), hover (gradiente naranja), active (blanco sólido).

default
hover
active
<ServiceCenterIcon size={28} state="default" />
<ServiceCenterIcon size={28} state="hover" />
<ServiceCenterIcon size={28} state="active" />

Tamaños

Acepta cualquier número de px. Default 24.

<ServiceCenterIcon size={16} />
<ServiceCenterIcon size={24} />
<ServiceCenterIcon size={32} />
<ServiceCenterIcon size={40} />

Interactivo (sin prop state)

Sin el prop state, el icono trackea sus propios eventos de mouse. Hovea o haz click para ver la transición.

<ServiceCenterIcon size={32} />

API

PropTipoDefault
size
Ancho y alto del SVG en px.
number24
state
Estado visual controlado. Omitir para modo autónomo (mouse tracking interno).
"default" | "hover" | "active"
title
Texto accesible. Sin él el icono es decorativo (aria-hidden).
string
className
Clases extra sobre el <svg>.
string""

Código del componente

Ver ServiceCenterIcon.tsx completo · self-contained · zero deps
ServiceCenterIcon.tsx
"use client";

import { useId, useState } from "react";
import type { JSX } from "react";

export interface ServiceCenterIconProps {
  size?: number;
  /** Controlled visual state — omit to let the icon track its own hover/active */
  state?: "default" | "hover" | "active";
  title?: string;
  className?: string;
}

export default function ServiceCenterIcon({ size = 24, state: controlled, title, className = "" }: ServiceCenterIconProps): JSX.Element {
  const uid = useId().replace(/:/g, "-");
  const [hovered, setHovered] = useState(false);
  const [pressed,  setPressed]  = useState(false);

  const resolved = controlled ?? (pressed ? "active" : hovered ? "hover" : "default");
  const isActive = resolved === "active";
  const isHover  = resolved === "hover";
  const paint    = isActive ? "white" : `url(#${uid}g)`;

  const handlers = controlled ? {} : {
    onMouseEnter: () => setHovered(true),
    onMouseLeave: () => { setHovered(false); setPressed(false); },
    onMouseDown:  () => setPressed(true),
    onMouseUp:    () => setPressed(false),
  };

  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      className={className}
      role={title ? "img" : undefined}
      aria-hidden={title ? undefined : true}
      style={{ flexShrink: 0 }}
      {...handlers}
    >
      {title && <title>{title}</title>}

      {!isActive && (
        <defs>
          {isHover ? (
            <linearGradient id={`${uid}g`} x1="12" y1="1" x2="12" y2="21" gradientUnits="userSpaceOnUse">
              <stop stopColor="#FF9639"/>
              <stop offset="0.4" stopColor="#EF852E"/>
              <stop offset="1" stopColor="#BE3D00"/>
            </linearGradient>
          ) : (
            <linearGradient id={`${uid}g`} x1="6.22694" y1="-11.3077" x2="28.0368" y2="-6.01905" gradientUnits="userSpaceOnUse">
              <stop stopColor="#CFBAFF"/>
              <stop offset="0.35" stopColor="white"/>
              <stop offset="0.65" stopColor="#AE8EFF"/>
              <stop offset="1" stopColor="#CFBAFF"/>
            </linearGradient>
          )}
        </defs>
      )}

      <path
        d="M11.9 17C12.25 17 12.5458 16.8792 12.7875 16.6375C13.0292 16.3958 13.15 16.1 13.15 15.75C13.15 15.4 13.0292 15.1042 12.7875 14.8625C12.5458 14.6208 12.25 14.5 11.9 14.5C11.55 14.5 11.2542 14.6208 11.0125 14.8625C10.7708 15.1042 10.65 15.4 10.65 15.75C10.65 16.1 10.7708 16.3958 11.0125 16.6375C11.2542 16.8792 11.55 17 11.9 17ZM11 13.15H12.85C12.85 12.8667 12.8625 12.625 12.8875 12.425C12.9125 12.225 12.9667 12.0333 13.05 11.85C13.1333 11.6667 13.2375 11.4958 13.3625 11.3375C13.4875 11.1792 13.6667 10.9833 13.9 10.75C14.4833 10.1667 14.8958 9.67917 15.1375 9.2875C15.3792 8.89583 15.5 8.45 15.5 7.95C15.5 7.06667 15.2 6.35417 14.6 5.8125C14 5.27083 13.1917 5 12.175 5C11.2583 5 10.4792 5.225 9.8375 5.675C9.19583 6.125 8.75 6.75 8.5 7.55L10.15 8.2C10.2667 7.75 10.5 7.3875 10.85 7.1125C11.2 6.8375 11.6083 6.7 12.075 6.7C12.525 6.7 12.9 6.82083 13.2 7.0625C13.5 7.30417 13.65 7.625 13.65 8.025C13.65 8.30833 13.5583 8.60833 13.375 8.925C13.1917 9.24167 12.8833 9.59167 12.45 9.975C12.1667 10.2083 11.9375 10.4375 11.7625 10.6625C11.5875 10.8875 11.4417 11.125 11.325 11.375C11.2083 11.625 11.125 11.8875 11.075 12.1625C11.025 12.4375 11 12.7667 11 13.15ZM12 23L9 20H5C4.45 20 3.97917 19.8042 3.5875 19.4125C3.19583 19.0208 3 18.55 3 18V4C3 3.45 3.19583 2.97917 3.5875 2.5875C3.97917 2.19583 4.45 2 5 2H19C19.55 2 20.0208 2.19583 20.4125 2.5875C20.8042 2.97917 21 3.45 21 4V18C21 18.55 20.8042 19.0208 20.4125 19.4125C20.0208 19.8042 19.55 20 19 20H15L12 23ZM5 18H9.8L12 20.2L14.2 18H19V4H5V18Z"
        fill={paint}
      />
    </svg>
  );
}