- 18 more icons (gamepad, computer, food, ...) with a test that keeps the server whitelist and the client picker identical. - The ⋯ menu of a message moves into the bubble foot (next to the time); its popup opens upwards inside the bubble and is limited to the bubble's width. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
344 lines
10 KiB
TypeScript
344 lines
10 KiB
TypeScript
import type { ReactNode } from "react";
|
|
|
|
/**
|
|
* Line icons drawn with `currentColor`: they take the text colour of their
|
|
* context, so every theme colours them (no per-theme icon sets needed).
|
|
*/
|
|
const P: Record<string, ReactNode> = {
|
|
menu: <path d="M4 6h16M4 12h16M4 18h16" />,
|
|
close: <path d="M6 6l12 12M18 6 6 18" />,
|
|
check: <path d="m5 12.5 4.5 4.5L19 7" />,
|
|
"x-mark": <path d="M7 7l10 10M17 7 7 17" />,
|
|
"arrow-up": <path d="M12 19V5M6 11l6-6 6 6" />,
|
|
"arrow-down": <path d="M12 5v14M6 13l6 6 6-6" />,
|
|
"arrow-left": <path d="M19 12H5M11 6l-6 6 6 6" />,
|
|
"arrow-right": <path d="M5 12h14M13 6l6 6-6 6" />,
|
|
"chevron-right": <path d="m9 6 6 6-6 6" />,
|
|
"chevron-down": <path d="m6 9 6 6 6-6" />,
|
|
share: (
|
|
<>
|
|
<circle cx="18" cy="5.5" r="2.5" />
|
|
<circle cx="6" cy="12" r="2.5" />
|
|
<circle cx="18" cy="18.5" r="2.5" />
|
|
<path d="m8.2 10.8 7.6-4M8.2 13.2l7.6 4" />
|
|
</>
|
|
),
|
|
fork: (
|
|
<>
|
|
<circle cx="6" cy="5" r="2" />
|
|
<circle cx="18" cy="5" r="2" />
|
|
<circle cx="12" cy="19" r="2" />
|
|
<path d="M6 7v2a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3V7M12 12v5" />
|
|
</>
|
|
),
|
|
download: <path d="M12 4v11M7 10l5 5 5-5M5 20h14" />,
|
|
compact: <path d="M8 4l4 4 4-4M8 20l4-4 4 4M4 12h16" />,
|
|
trash: <path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13M10 11v6M14 11v6" />,
|
|
gamepad: (
|
|
<>
|
|
<path d="M7 8h10a4 4 0 0 1 4 4.2l-.6 3.8a2.4 2.4 0 0 1-4.1 1.3L14 15h-4l-2.3 2.3a2.4 2.4 0 0 1-4.1-1.3L3 12.2A4 4 0 0 1 7 8Z" />
|
|
<path d="M8 10.5v3M6.5 12h3M15.5 11h.01M17.5 13h.01" />
|
|
</>
|
|
),
|
|
computer: (
|
|
<>
|
|
<rect x="3" y="4" width="18" height="12" rx="2" />
|
|
<path d="M8 20h8M12 16v4" />
|
|
</>
|
|
),
|
|
food: (
|
|
<>
|
|
<path d="M5 3v6a2 2 0 0 0 4 0V3M7 11v10" />
|
|
<path d="M17 21V3c-2.6 1.4-3.5 4.2-3.5 7.5H17" />
|
|
</>
|
|
),
|
|
home: (
|
|
<>
|
|
<path d="M4 11.5 12 4l8 7.5V20H4Z" />
|
|
<path d="M10 20v-5h4v5" />
|
|
</>
|
|
),
|
|
book: (
|
|
<>
|
|
<path d="M5 4h11a3 3 0 0 1 3 3v13H8a3 3 0 0 1-3-3Z" />
|
|
<path d="M5 17a3 3 0 0 1 3-3h11" />
|
|
</>
|
|
),
|
|
code: <path d="m8 7-5 5 5 5M16 7l5 5-5 5M14 5l-4 14" />,
|
|
camera: (
|
|
<>
|
|
<path d="M4 8h3l1.5-2h7L17 8h3v11H4Z" />
|
|
<circle cx="12" cy="13" r="3.5" />
|
|
</>
|
|
),
|
|
cart: (
|
|
<>
|
|
<path d="M3 4h2.5l2 11h10l2-8H7" />
|
|
<circle cx="9" cy="19" r="1.4" />
|
|
<circle cx="17" cy="19" r="1.4" />
|
|
</>
|
|
),
|
|
heart: <path d="M12 20s-8-4.6-8-10.5A4.5 4.5 0 0 1 12 7a4.5 4.5 0 0 1 8 2.5C20 15.4 12 20 12 20Z" />,
|
|
star: <path d="m12 3.5 2.6 5.4 5.9.8-4.3 4.1 1 5.9L12 16.9l-5.2 2.8 1-5.9-4.3-4.1 5.9-.8Z" />,
|
|
globe: (
|
|
<>
|
|
<circle cx="12" cy="12" r="8.5" />
|
|
<path d="M3.5 12h17M12 3.5c3 3 3 14 0 17M12 3.5c-3 3-3 14 0 17" />
|
|
</>
|
|
),
|
|
calendar: (
|
|
<>
|
|
<rect x="4" y="5" width="16" height="15" rx="2" />
|
|
<path d="M4 10h16M8 3v4M16 3v4" />
|
|
</>
|
|
),
|
|
coffee: (
|
|
<>
|
|
<path d="M5 9h11v5a5 5 0 0 1-5 5H10a5 5 0 0 1-5-5Z" />
|
|
<path d="M16 10h1.5a2.5 2.5 0 0 1 0 5H16M8 3v3M12 3v3" />
|
|
</>
|
|
),
|
|
car: (
|
|
<>
|
|
<path d="M3.5 16v-4l2-5h13l2 5v4Z" />
|
|
<path d="M3.5 12h17" />
|
|
<circle cx="7.5" cy="16" r="1.5" />
|
|
<circle cx="16.5" cy="16" r="1.5" />
|
|
</>
|
|
),
|
|
plane: (
|
|
<>
|
|
<path d="M21 3 3 10.5l6.5 2.5L12 20Z" />
|
|
<path d="M9.5 13 21 3" />
|
|
</>
|
|
),
|
|
bulb: <path d="M9 18h6M10 21h4M12 3a6 6 0 0 0-3.5 10.9c.6.5 1 1.3 1 2.1h5c0-.8.4-1.6 1-2.1A6 6 0 0 0 12 3Z" />,
|
|
money: (
|
|
<>
|
|
<circle cx="12" cy="12" r="8.5" />
|
|
<path d="M14.5 9.2c-.5-.8-1.4-1.2-2.5-1.2-1.5 0-2.5.8-2.5 1.9 0 2.7 5 1.2 5 4 0 1.1-1 2-2.5 2-1.1 0-2.1-.5-2.6-1.4M12 6.5V8M12 16v1.5" />
|
|
</>
|
|
),
|
|
palette: (
|
|
<>
|
|
<path d="M12 3.5a8.5 8.5 0 1 0 0 17c1.3 0 1.8-1 1.3-2-.6-1.2.2-2.5 1.6-2.5H17a3.5 3.5 0 0 0 3.5-3.5C20.5 7 16.8 3.5 12 3.5Z" />
|
|
<path d="M7.5 11h.01M9.5 7.5h.01M14 7.5h.01" />
|
|
</>
|
|
),
|
|
reply: <path d="M9 7 4 12l5 5M4 12h9a7 7 0 0 1 7 7" />,
|
|
edit: <path d="M4 20h4L19 9l-4-4L4 16v4ZM13.5 6.5l4 4" />,
|
|
undo: <path d="M9 14 4 9l5-5M4 9h10a6 6 0 0 1 0 12h-3" />,
|
|
clip: <path d="m20 11-8.5 8.5a5 5 0 0 1-7-7L13 4a3.5 3.5 0 0 1 5 5l-8.5 8.5a2 2 0 0 1-3-3L14 7" />,
|
|
file: (
|
|
<>
|
|
<path d="M6 3h8l4 4v14H6Z" />
|
|
<path d="M14 3v4h4" />
|
|
</>
|
|
),
|
|
"file-text": (
|
|
<>
|
|
<path d="M6 3h8l4 4v14H6Z" />
|
|
<path d="M14 3v4h4M9 12h6M9 16h6" />
|
|
</>
|
|
),
|
|
"file-doc": (
|
|
<>
|
|
<path d="M6 3h8l4 4v14H6Z" />
|
|
<path d="M14 3v4h4M9 11h6M9 14h6M9 17h4" />
|
|
</>
|
|
),
|
|
folder: <path d="M3 6a1 1 0 0 1 1-1h5l2 2h9a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1Z" />,
|
|
"folder-up": (
|
|
<>
|
|
<path d="M3 6a1 1 0 0 1 1-1h5l2 2h9a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1Z" />
|
|
<path d="M12 16v-5M9.5 13.5 12 11l2.5 2.5" />
|
|
</>
|
|
),
|
|
folders: (
|
|
<>
|
|
<path d="M7 8a1 1 0 0 1 1-1h4l1.5 1.5H20a1 1 0 0 1 1 1V18a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1Z" />
|
|
<path d="M4 15V6a1 1 0 0 1 1-1h4" />
|
|
</>
|
|
),
|
|
image: (
|
|
<>
|
|
<rect x="3" y="5" width="18" height="14" rx="2" />
|
|
<circle cx="9" cy="10" r="1.8" />
|
|
<path d="m4 17 5-4 4 3 3-2 4 3" />
|
|
</>
|
|
),
|
|
music: (
|
|
<>
|
|
<path d="M9 18V6l11-2v12" />
|
|
<circle cx="6.5" cy="18" r="2.5" />
|
|
<circle cx="17.5" cy="16" r="2.5" />
|
|
</>
|
|
),
|
|
cube: (
|
|
<>
|
|
<path d="m12 3 8 4.5v9L12 21l-8-4.5v-9Z" />
|
|
<path d="m4 7.5 8 4.5 8-4.5M12 12v9" />
|
|
</>
|
|
),
|
|
external: <path d="M14 4h6v6M20 4l-9 9M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5" />,
|
|
refresh: <path d="M20 11a8 8 0 1 0-2.3 5.7M20 4v7h-7" />,
|
|
lock: (
|
|
<>
|
|
<rect x="5" y="11" width="14" height="9" rx="2" />
|
|
<path d="M8 11V8a4 4 0 0 1 8 0v3M12 15v2" />
|
|
</>
|
|
),
|
|
question: (
|
|
<>
|
|
<circle cx="12" cy="12" r="9" />
|
|
<path d="M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .8-1 1.5V14M12 17h.01" />
|
|
</>
|
|
),
|
|
"radio-on": (
|
|
<>
|
|
<circle cx="12" cy="12" r="8" />
|
|
<circle cx="12" cy="12" r="3.5" className="fill" />
|
|
</>
|
|
),
|
|
"radio-off": <circle cx="12" cy="12" r="8" />,
|
|
"box-on": (
|
|
<>
|
|
<rect x="4" y="4" width="16" height="16" rx="3" />
|
|
<path d="m8 12 3 3 5-6" />
|
|
</>
|
|
),
|
|
"box-off": <rect x="4" y="4" width="16" height="16" rx="3" />,
|
|
play: <path d="M8 5v14l11-7Z" className="fill" />,
|
|
stop: <rect x="6" y="6" width="12" height="12" rx="2" className="fill" />,
|
|
warning: <path d="M12 4 2.5 20h19ZM12 10v4.5M12 17.5h.01" />,
|
|
brain: (
|
|
<>
|
|
<path d="M9 4a3 3 0 0 0-3 3 3 3 0 0 0-2 5 3 3 0 0 0 2 5 3 3 0 0 0 6 1V5a2 2 0 0 0-3-1Z" />
|
|
<path d="M15 4a3 3 0 0 1 3 3 3 3 0 0 1 2 5 3 3 0 0 1-2 5 3 3 0 0 1-6 1" />
|
|
</>
|
|
),
|
|
search: (
|
|
<>
|
|
<circle cx="11" cy="11" r="6.5" />
|
|
<path d="m16 16 4.5 4.5" />
|
|
</>
|
|
),
|
|
eye: (
|
|
<>
|
|
<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z" />
|
|
<circle cx="12" cy="12" r="3" />
|
|
</>
|
|
),
|
|
gear: (
|
|
<>
|
|
<circle cx="12" cy="12" r="3" />
|
|
<path d="M12 2.5v3M12 18.5v3M21.5 12h-3M5.5 12h-3M18.7 5.3l-2.1 2.1M7.4 16.6l-2.1 2.1M18.7 18.7l-2.1-2.1M7.4 7.4 5.3 5.3" />
|
|
</>
|
|
),
|
|
robot: (
|
|
<>
|
|
<rect x="5" y="8" width="14" height="11" rx="3" />
|
|
<path d="M12 4v4M9 13h.01M15 13h.01M9.5 16h5M3 12v3M21 12v3" />
|
|
</>
|
|
),
|
|
plug: <path d="M9 3v5M15 3v5M6 8h12v3a6 6 0 0 1-12 0ZM12 17v4" />,
|
|
shield: (
|
|
<>
|
|
<path d="M12 3 5 6v6c0 4.2 3 7.6 7 9 4-1.4 7-4.8 7-9V6Z" />
|
|
<path d="m9 12 2 2 4-4" />
|
|
</>
|
|
),
|
|
users: (
|
|
<>
|
|
<circle cx="9" cy="8" r="3.2" />
|
|
<path d="M3 20a6 6 0 0 1 12 0M16 4.5a3.2 3.2 0 0 1 0 6.3M18 14.5a6 6 0 0 1 3 5.5" />
|
|
</>
|
|
),
|
|
user: (
|
|
<>
|
|
<circle cx="12" cy="8" r="3.8" />
|
|
<path d="M4.5 20.5a7.5 7.5 0 0 1 15 0" />
|
|
</>
|
|
),
|
|
toolbox: (
|
|
<>
|
|
<rect x="3" y="8" width="18" height="11" rx="2" />
|
|
<path d="M9 8V5h6v3M3 13h18M10 12v2M14 12v2" />
|
|
</>
|
|
),
|
|
scroll: <path d="M7 4h11a2 2 0 0 1 0 4h-1v10a2 2 0 0 1-2 2H6a2 2 0 0 1 0-4h1ZM10 9h4M10 12h4" />,
|
|
terminal: (
|
|
<>
|
|
<rect x="3" y="4" width="18" height="16" rx="2" />
|
|
<path d="m7 9 3 3-3 3M12 15h5" />
|
|
</>
|
|
),
|
|
logout: <path d="M10 4H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5M15 8l4 4-4 4M19 12H9" />,
|
|
chart: <path d="M4 20V4M4 20h16M8 16v-4M12 16V8M16 16v-6M20 16V6" />,
|
|
wrench: <path d="M14.5 5.5a4 4 0 0 0 5 5L11 19a2.1 2.1 0 0 1-3-3l8.5-8.5a4 4 0 0 1-2-2Z" />,
|
|
sun: (
|
|
<>
|
|
<circle cx="12" cy="12" r="4" />
|
|
<path d="M12 2.5v2M12 19.5v2M21.5 12h-2M4.5 12h-2M18.7 5.3l-1.4 1.4M6.7 17.3l-1.4 1.4M18.7 18.7l-1.4-1.4M6.7 6.7 5.3 5.3" />
|
|
</>
|
|
),
|
|
moon: <path d="M20 14.5A8 8 0 1 1 9.5 4a6.5 6.5 0 0 0 10.5 10.5Z" />,
|
|
"theme-auto": (
|
|
<>
|
|
<circle cx="12" cy="12" r="8.5" />
|
|
<path d="M12 3.5v17a8.5 8.5 0 0 0 0-17Z" className="fill" />
|
|
</>
|
|
),
|
|
dot: <circle cx="12" cy="12" r="4.5" className="fill" />,
|
|
plus: <path d="M12 5v14M5 12h14" />,
|
|
pin: <path d="M9 4h6l-1 5 3 3v2H7v-2l3-3-1-5ZM12 14v6" />,
|
|
archive: <path d="M4 5h16v4H4ZM5 9v10h14V9M10 13h4" />,
|
|
template: <path d="M5 4h14a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1ZM8 9h8M8 12.5h8M8 16h4.5" />,
|
|
mic: (
|
|
<>
|
|
<rect x="9" y="3" width="6" height="11" rx="3" />
|
|
<path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6" />
|
|
</>
|
|
),
|
|
clock: (
|
|
<>
|
|
<circle cx="12" cy="12" r="8.5" />
|
|
<path d="M12 7.5V12l3 2" />
|
|
</>
|
|
),
|
|
minus: <path d="M5 12h14" />,
|
|
upload: <path d="M12 16V4M7 9l5-5 5 5M4 16v3a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-3" />,
|
|
more: (
|
|
<>
|
|
<circle cx="5" cy="12" r="1.6" className="fill" />
|
|
<circle cx="12" cy="12" r="1.6" className="fill" />
|
|
<circle cx="19" cy="12" r="1.6" className="fill" />
|
|
</>
|
|
),
|
|
copy: (
|
|
<>
|
|
<rect x="8" y="8" width="12" height="12" rx="2" />
|
|
<path d="M16 8V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3" />
|
|
</>
|
|
),
|
|
sparkle: <path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8Z" />,
|
|
};
|
|
|
|
export type IconName = keyof typeof P;
|
|
|
|
export function Icon({ name, size, className, title }: { name: string; size?: number; className?: string; title?: string }) {
|
|
return (
|
|
<svg
|
|
className={`icon ${className ?? ""}`}
|
|
viewBox="0 0 24 24"
|
|
width={size}
|
|
height={size}
|
|
aria-hidden={title ? undefined : true}
|
|
role={title ? "img" : undefined}
|
|
>
|
|
{title && <title>{title}</title>}
|
|
{P[name] ?? P.dot}
|
|
</svg>
|
|
);
|
|
}
|