Snippets

SVG Icon Component

Convert any SVG into a dynamic Icon component similar to react-icons (See also: react-icons)

TSX

/**
 * A simple custom icon created from an SVG
 * and adapted to have dynamic size and current color of parent.
 *
 * This particular SVG is for X and was adapted from here:
 * @link https://about.twitter.com/en/who-we-are/brand-toolkit
 */
export function TwitterX({
  size: propSize = 20,
  className,
  title,
  color,
}: IconProps) {
  const aspectRatio = 1;
  const size = Number(propSize);
  const width = size - 4; // A size adjustment specific to this SVG (not required)
  const height = width / aspectRatio;

  return (
    <svg
      width={width}
      height={height}
      viewBox="0 0 24 24"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      strokeLinejoin="round"
      color={color}
    >
      {title ? <title>{title}</title> : null}
      <path
        className={className}
        d="M14.0158 10.2386L22.2058 0.92308H20.2651L13.1537 9.0116L7.47386 0.92308H0.922852L9.51187 13.1543L0.922852 22.9231H2.86373L10.3735 14.3813L16.3718 22.9231H22.9229L14.0154 10.2386H14.0158ZM11.3575 13.2621L10.4873 12.0442L3.56305 2.35273H6.54413L12.1321 10.174L13.0023 11.392L20.266 21.5585H17.2849L11.3575 13.2626V13.2621Z"
        fill={"currentColor"}
        stroke={"currentColor"}
      />
    </svg>
  );
}

/**
 * Basic icon props as present on react-icons
 */
type IconProps = {
  size?: number | string;
  className?: string;
  title?: string;
  color?: string;
};
/**
 * A simple custom icon created from an SVG
 * and adapted to have dynamic size and current color of parent.
 *
 * This particular SVG is for X and was adapted from here:
 * @link https://about.twitter.com/en/who-we-are/brand-toolkit
 */
export function TwitterX({
  size: propSize = 20,
  className,
  title,
  color,
}: IconProps) {
  const aspectRatio = 1;
  const size = Number(propSize);
  const width = size - 4; // A size adjustment specific to this SVG (not required)
  const height = width / aspectRatio;

  return (
    <svg
      width={width}
      height={height}
      viewBox="0 0 24 24"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      strokeLinejoin="round"
      color={color}
    >
      {title ? <title>{title}</title> : null}
      <path
        className={className}
        d="M14.0158 10.2386L22.2058 0.92308H20.2651L13.1537 9.0116L7.47386 0.92308H0.922852L9.51187 13.1543L0.922852 22.9231H2.86373L10.3735 14.3813L16.3718 22.9231H22.9229L14.0154 10.2386H14.0158ZM11.3575 13.2621L10.4873 12.0442L3.56305 2.35273H6.54413L12.1321 10.174L13.0023 11.392L20.266 21.5585H17.2849L11.3575 13.2626V13.2621Z"
        fill={"currentColor"}
        stroke={"currentColor"}
      />
    </svg>
  );
}

/**
 * Basic icon props as present on react-icons
 */
type IconProps = {
  size?: number | string;
  className?: string;
  title?: string;
  color?: string;
};

Examples

Socials.tsx

A social bar for rendering social links

TSX

import Link from "next/link";
import { LuFacebook, LuInstagram } from "react-icons/lu";
import { TwitterX } from "./TwitterX";

const SOCIALS = [
  {
    name: "Facebook",
    url: "https://www.facebook.com/",
    Icon: LuFacebook,
    ariaLabel: "Facebook profile",
    className: "stroke-blue-600 dark:stroke-blue-400",
  },
  {
    name: "Twitter",
    url: "https://twitter.com",
    Icon: TwitterX,
    ariaLabel: "Twitter profile",
    className:
      "stroke-slate-800 fill-slate-800 dark:fill-slate-200 dark:stroke-slate-200",
  },
  {
    name: "Instagram",
    url: "https://www.instagram.com/",
    Icon: LuInstagram,
    ariaLabel: "Instagram profile",
    className: "stroke-red-500 dark:stroke-red-400",
  },
];

export function Socials() {
  return (
    <div className="flex items-center gap-2">
      <span>Follow me on:</span>
      <div className="flex items-center gap-3 w-fit border p-2 rounded-md dark:border-gray-500 border-gray-600">
        {SOCIALS.map((social) => {
          return (
            <Link
              key={social.name}
              href={social.url}
              aria-label={social.ariaLabel}
              className={"hover:scale-110 transition-transform"}
            >
              <social.Icon
                className={social.className}
                size={30}
                title={social.name}
              />
            </Link>
          );
        })}
      </div>
    </div>
  );
}
import Link from "next/link";
import { LuFacebook, LuInstagram } from "react-icons/lu";
import { TwitterX } from "./TwitterX";

const SOCIALS = [
  {
    name: "Facebook",
    url: "https://www.facebook.com/",
    Icon: LuFacebook,
    ariaLabel: "Facebook profile",
    className: "stroke-blue-600 dark:stroke-blue-400",
  },
  {
    name: "Twitter",
    url: "https://twitter.com",
    Icon: TwitterX,
    ariaLabel: "Twitter profile",
    className:
      "stroke-slate-800 fill-slate-800 dark:fill-slate-200 dark:stroke-slate-200",
  },
  {
    name: "Instagram",
    url: "https://www.instagram.com/",
    Icon: LuInstagram,
    ariaLabel: "Instagram profile",
    className: "stroke-red-500 dark:stroke-red-400",
  },
];

export function Socials() {
  return (
    <div className="flex items-center gap-2">
      <span>Follow me on:</span>
      <div className="flex items-center gap-3 w-fit border p-2 rounded-md dark:border-gray-500 border-gray-600">
        {SOCIALS.map((social) => {
          return (
            <Link
              key={social.name}
              href={social.url}
              aria-label={social.ariaLabel}
              className={"hover:scale-110 transition-transform"}
            >
              <social.Icon
                className={social.className}
                size={30}
                title={social.name}
              />
            </Link>
          );
        })}
      </div>
    </div>
  );
}

Demo - Social Links

r.e

© 2021-2024 Rexford Essilfie. All rights reserved.