Aubia Logo
English

Botón

Playground de Botón

Dependencias

npm.shbash
Recommended path: terminal
1npm install react-icons

Uso

ButtonExample.tsxtsx
Recommended path: app/components/button/ButtonExample.tsx
1import { Button } from "@/src/components/shared/Button";
2
3export default function Example() {
4  return (
5    <Button
6      variant="fill"
7      color="#62009e"
8      widthMode="fit"
9      rounded="full"
10      onlyIcon={false}
11      shadowInHover={true}
12    >
13      {"Ponte en contacto"}
14    </Button>
15  );
16}

Componente

Button.tsxtsx
Recommended path: src/components/shared/Button.tsx
1"use client";
2import React, { useRef } from "react";
3
4export const Button: React.FC<{
5  children: React.ReactNode;
6  onlyIcon?: boolean;
7  variant?: "fill" | "outline";
8  color?: string;
9  rounded?: number | "full";
10  shadowInHover?: boolean;
11  widthMode?: "full" | "fit";
12}> = ({
13  children,
14  onlyIcon = false,
15  variant = "fill",
16  color = "#62009e",
17  rounded = "full",
18  shadowInHover = true,
19  widthMode = "fit",
20}) => {
21  const buttonRef = useRef<HTMLButtonElement>(null);
22
23  const shadow = () => {
24    if (buttonRef.current) {
25      buttonRef.current.style.boxShadow = `0px 0px 10px ${color}`;
26    }
27  };
28
29  const shadowOut = () => {
30    if (buttonRef.current) {
31      buttonRef.current.style.boxShadow = "none";
32    }
33  };
34
35  const parseHexToRgb = (hexColor: string) => {
36    const normalized = hexColor.trim().replace("#", "");
37
38    if (normalized.length === 3) {
39      const r = parseInt(normalized[0] + normalized[0], 16);
40      const g = parseInt(normalized[1] + normalized[1], 16);
41      const b = parseInt(normalized[2] + normalized[2], 16);
42      return { r, g, b };
43    }
44
45    if (normalized.length === 6) {
46      const r = parseInt(normalized.slice(0, 2), 16);
47      const g = parseInt(normalized.slice(2, 4), 16);
48      const b = parseInt(normalized.slice(4, 6), 16);
49      return { r, g, b };
50    }
51
52    return null;
53  };
54
55  const resolveTextColor = () => {
56    if (variant === "outline") {
57      return color;
58    }
59
60    const rgb = parseHexToRgb(color);
61    if (rgb) {
62      const { r, g, b } = rgb;
63      const brightness = (r * 299 + g * 587 + b * 114) / 1000;
64      return brightness > 125 ? "#000" : "#fff";
65    }
66
67    return "#fff";
68  };
69
70  return (
71    <button
72      ref={buttonRef}
73      className={`${onlyIcon ? "p-2" : "p-2 px-4"}  font-semibold cursor-pointer transition-all duration-300 active:scale-95 ${widthMode === "full" ? "w-full" : "w-fit"} `}
74      style={{
75        background: variant === "fill" ? color : "transparent",
76        borderColor: variant === "outline" ? color : "transparent",
77        borderRadius: rounded === "full" ? "9999px" : `${rounded}px`,
78        color: resolveTextColor(),
79        borderWidth: variant === "outline" ? "2px" : "0",
80      }}
81      onMouseEnter={() => shadowInHover && shadow()}
82      onMouseLeave={() => shadowInHover && shadowOut()}
83    >
84      {children}
85    </button>
86  );
87};
88
89export default Button;
90