timconspicuous.neocities.org
1import * as si from "npm:simple-icons@13.10.0";
2import type { SimpleIcon } from "npm:simple-icons@13.10.0";
3
4export default function ({
5 link,
6}: {
7 link: {
8 type: string;
9 text: string;
10 href: string;
11 hex?: string;
12 textColor?: string;
13 only_icon?: boolean;
14 };
15}) {
16 // Get the icon information directly from simple-icons
17 const icons = Object.values(si) as SimpleIcon[];
18 const icon = icons.find((icon) => icon.slug === link.type);
19
20 // Use the specified hex or get it from the icon (or default to white)
21 const hex = link.hex || (icon ? `#${icon.hex}` : "#fff");
22
23 // Function to determine text color based on background color brightness
24 const getTextColor = (backgroundColor: string) => {
25 // Remove the # if present and pad to 6 characters if needed
26 const color =
27 (backgroundColor.startsWith("#")
28 ? backgroundColor.slice(1)
29 : backgroundColor).padEnd(
30 6,
31 backgroundColor.length <= 4
32 ? backgroundColor.slice(-1)
33 : "",
34 );
35
36 // Convert hex to RGB
37 const r = parseInt(color.substring(0, 2), 16);
38 const g = parseInt(color.substring(2, 4), 16);
39 const b = parseInt(color.substring(4, 6), 16);
40
41 // Calculate luminance to determine perceived brightness
42 const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
43
44 // Return black for light backgrounds, white for dark ones
45 return luminance > 128 ? "#000000" : "#ffffff";
46 };
47
48 const textColor = link.textColor || getTextColor(hex);
49
50 return (
51 <a
52 href={link.href}
53 class="button"
54 style={`--bg-color:${hex}; --text-color:${textColor}`}
55 title={link.only_icon ? link.text : undefined}
56 dangerouslySetInnerHTML={{
57 __html: `${icon ? icon.svg : ""}${
58 !link.only_icon ? link.text : ""
59 }`,
60 }}
61 />
62 );
63}