AkurAI Build
Menu

Public repository / 8b66e18ce8cb51ca3e4124f89fd1429a1d4792f3

AkurAI-Mail / src/framework/icons.js

Latest change 3af23b0e937520000e1aa43c7e2eb9de2675abd1 - OLI-248: webmail list and reader as framework islands on a signals store by Ólafur Búi Ólafsson

// icons.js — inline SVG icons for AkurAI Mail (no build step, no runtime dependency).
// Path data from Lucide (https://lucide.dev), ISC License, Copyright (c) Lucide Icons and Contributors;
// icons derived from Feather are MIT, Copyright (c) 2013-present Cole Bemis. Generated by scripts/gen-icons.ts.

const SVG_NS = "http://www.w3.org/2000/svg";

/** @type {Record<string, [string, Record<string, string>][]>} */
export const ICONS = {
  Archive: [["rect", { "width": "20", "height": "5", "x": "2", "y": "3", "rx": "1" }], ["path", { "d": "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" }], ["path", { "d": "M10 12h4" }]],
  ArrowLeft: [["path", { "d": "m12 19-7-7 7-7" }], ["path", { "d": "M19 12H5" }]],
  Bell: [["path", { "d": "M10.268 21a2 2 0 0 0 3.464 0" }], ["path", { "d": "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" }]],
  Bold: [["path", { "d": "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" }]],
  Bot: [["path", { "d": "M12 8V4H8" }], ["rect", { "width": "16", "height": "12", "x": "4", "y": "8", "rx": "2" }], ["path", { "d": "M2 14h2" }], ["path", { "d": "M20 14h2" }], ["path", { "d": "M15 13v2" }], ["path", { "d": "M9 13v2" }]],
  Check: [["path", { "d": "M20 6 9 17l-5-5" }]],
  ChevronDown: [["path", { "d": "m6 9 6 6 6-6" }]],
  ChevronLeft: [["path", { "d": "m15 18-6-6 6-6" }]],
  ChevronRight: [["path", { "d": "m9 18 6-6-6-6" }]],
  CircleHelp: [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }], ["path", { "d": "M12 17h.01" }]],
  Clock: [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "M12 6v6l4 2" }]],
  Clock3: [["circle", { "cx": "12", "cy": "12", "r": "10" }], ["path", { "d": "M12 6v6h4" }]],
  Download: [["path", { "d": "M12 15V3" }], ["path", { "d": "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }], ["path", { "d": "m7 10 5 5 5-5" }]],
  FilePen: [["path", { "d": "M12.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v9.34" }], ["path", { "d": "M14 2v5a1 1 0 0 0 1 1h5" }], ["path", { "d": "M10.378 12.622a1 1 0 0 1 3 3.003L8.36 20.637a2 2 0 0 1-.854.506l-2.867.837a.5.5 0 0 1-.62-.62l.836-2.869a2 2 0 0 1 .506-.853z" }]],
  FileText: [["path", { "d": "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }], ["path", { "d": "M14 2v5a1 1 0 0 0 1 1h5" }], ["path", { "d": "M10 9H8" }], ["path", { "d": "M16 13H8" }], ["path", { "d": "M16 17H8" }]],
  Flag: [["path", { "d": "M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528" }]],
  FolderInput: [["path", { "d": "M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1" }], ["path", { "d": "M2 13h10" }], ["path", { "d": "m9 16 3-3-3-3" }]],
  Forward: [["path", { "d": "m15 17 5-5-5-5" }], ["path", { "d": "M4 18v-2a4 4 0 0 1 4-4h12" }]],
  Inbox: [["polyline", { "points": "22 12 16 12 14 15 10 15 8 12 2 12" }], ["path", { "d": "M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" }]],
  Italic: [["line", { "x1": "19", "x2": "10", "y1": "4", "y2": "4" }], ["line", { "x1": "14", "x2": "5", "y1": "20", "y2": "20" }], ["line", { "x1": "15", "x2": "9", "y1": "4", "y2": "20" }]],
  Keyboard: [["path", { "d": "M10 8h.01" }], ["path", { "d": "M12 12h.01" }], ["path", { "d": "M14 8h.01" }], ["path", { "d": "M16 12h.01" }], ["path", { "d": "M18 8h.01" }], ["path", { "d": "M6 8h.01" }], ["path", { "d": "M7 16h10" }], ["path", { "d": "M8 12h.01" }], ["rect", { "width": "20", "height": "16", "x": "2", "y": "4", "rx": "2" }]],
  Link2: [["path", { "d": "M9 17H7A5 5 0 0 1 7 7h2" }], ["path", { "d": "M15 7h2a5 5 0 1 1 0 10h-2" }], ["line", { "x1": "8", "x2": "16", "y1": "12", "y2": "12" }]],
  List: [["path", { "d": "M3 5h.01" }], ["path", { "d": "M3 12h.01" }], ["path", { "d": "M3 19h.01" }], ["path", { "d": "M8 5h13" }], ["path", { "d": "M8 12h13" }], ["path", { "d": "M8 19h13" }]],
  ListOrdered: [["path", { "d": "M11 5h10" }], ["path", { "d": "M11 12h10" }], ["path", { "d": "M11 19h10" }], ["path", { "d": "M4 4h1v5" }], ["path", { "d": "M4 9h2" }], ["path", { "d": "M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02" }]],
  Mail: [["path", { "d": "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" }], ["rect", { "x": "2", "y": "4", "width": "20", "height": "16", "rx": "2" }]],
  MessageCircle: [["path", { "d": "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719" }]],
  MoreHorizontal: [["circle", { "cx": "12", "cy": "12", "r": "1" }], ["circle", { "cx": "19", "cy": "12", "r": "1" }], ["circle", { "cx": "5", "cy": "12", "r": "1" }]],
  Paperclip: [["path", { "d": "m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551" }]],
  PenLine: [["path", { "d": "M13 21h8" }], ["path", { "d": "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" }]],
  Plus: [["path", { "d": "M5 12h14" }], ["path", { "d": "M12 5v14" }]],
  Quote: [["path", { "d": "M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z" }], ["path", { "d": "M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z" }]],
  RefreshCcw: [["path", { "d": "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { "d": "M3 3v5h5" }], ["path", { "d": "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" }], ["path", { "d": "M16 16h5v5" }]],
  RefreshCw: [["path", { "d": "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }], ["path", { "d": "M21 3v5h-5" }], ["path", { "d": "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }], ["path", { "d": "M8 16H3v5" }]],
  Reply: [["path", { "d": "M20 18v-2a4 4 0 0 0-4-4H4" }], ["path", { "d": "m9 17-5-5 5-5" }]],
  ReplyAll: [["path", { "d": "m12 17-5-5 5-5" }], ["path", { "d": "M22 18v-2a4 4 0 0 0-4-4H7" }], ["path", { "d": "m7 17-5-5 5-5" }]],
  Search: [["path", { "d": "m21 21-4.34-4.34" }], ["circle", { "cx": "11", "cy": "11", "r": "8" }]],
  SearchCheck: [["path", { "d": "m8 11 2 2 4-4" }], ["circle", { "cx": "11", "cy": "11", "r": "8" }], ["path", { "d": "m21 21-4.3-4.3" }]],
  Send: [["path", { "d": "M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z" }], ["path", { "d": "m21.854 2.147-10.94 10.939" }]],
  ServerCog: [["path", { "d": "m10.852 14.772-.383.923" }], ["path", { "d": "M13.148 14.772a3 3 0 1 0-2.296-5.544l-.383-.923" }], ["path", { "d": "m13.148 9.228.383-.923" }], ["path", { "d": "m13.53 15.696-.382-.924a3 3 0 1 1-2.296-5.544" }], ["path", { "d": "m14.772 10.852.923-.383" }], ["path", { "d": "m14.772 13.148.923.383" }], ["path", { "d": "M4.5 10H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-.5" }], ["path", { "d": "M4.5 14H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2h-.5" }], ["path", { "d": "M6 18h.01" }], ["path", { "d": "M6 6h.01" }], ["path", { "d": "m9.228 10.852-.923-.383" }], ["path", { "d": "m9.228 13.148-.923.383" }]],
  Settings2: [["path", { "d": "M14 17H5" }], ["path", { "d": "M19 7h-9" }], ["circle", { "cx": "17", "cy": "17", "r": "3" }], ["circle", { "cx": "7", "cy": "7", "r": "3" }]],
  ShieldAlert: [["path", { "d": "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" }], ["path", { "d": "M12 8v4" }], ["path", { "d": "M12 16h.01" }]],
  SlidersHorizontal: [["path", { "d": "M10 5H3" }], ["path", { "d": "M12 19H3" }], ["path", { "d": "M14 3v4" }], ["path", { "d": "M16 17v4" }], ["path", { "d": "M21 12h-9" }], ["path", { "d": "M21 19h-5" }], ["path", { "d": "M21 5h-7" }], ["path", { "d": "M8 10v4" }], ["path", { "d": "M8 12H3" }]],
  Star: [["path", { "d": "M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z" }]],
  Trash2: [["path", { "d": "M10 11v6" }], ["path", { "d": "M14 11v6" }], ["path", { "d": "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }], ["path", { "d": "M3 6h18" }], ["path", { "d": "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }]],
  TriangleAlert: [["path", { "d": "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }], ["path", { "d": "M12 9v4" }], ["path", { "d": "M12 17h.01" }]],
  UserPlus: [["path", { "d": "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }], ["circle", { "cx": "9", "cy": "7", "r": "4" }], ["line", { "x1": "19", "x2": "19", "y1": "8", "y2": "14" }], ["line", { "x1": "22", "x2": "16", "y1": "11", "y2": "11" }]],
  WifiOff: [["path", { "d": "M12 20h.01" }], ["path", { "d": "M8.5 16.429a5 5 0 0 1 7 0" }], ["path", { "d": "M5 12.859a10 10 0 0 1 5.17-2.69" }], ["path", { "d": "M19 12.859a10 10 0 0 0-2.007-1.523" }], ["path", { "d": "M2 8.82a15 15 0 0 1 4.177-2.643" }], ["path", { "d": "M22 8.82a15 15 0 0 0-11.288-3.764" }], ["path", { "d": "m2 2 20 20" }]],
  X: [["path", { "d": "M18 6 6 18" }], ["path", { "d": "m6 6 12 12" }]],
};

/**
 * An inline SVG element for icon `name` (a key of ICONS).
 * @param {string} name
 * @param {{ size?: number, strokeWidth?: number, fill?: string, class?: string, label?: string }} [options]
 * @returns {SVGSVGElement}
 */
export function icon(name, { size = 24, strokeWidth = 2, fill = "none", class: className = "", label = "" } = {}) {
  // Accepts PascalCase keys and lucide's kebab-case names ("message-circle").
  const key = name.includes("-") || name[0] !== name[0].toUpperCase() ? name.replace(/(^|-)([a-z0-9])/g, (_, _sep, c) => c.toUpperCase()) : name;
  const nodes = ICONS[key];
  if (!nodes) throw new Error(`unknown icon ${name}`);
  const svg = document.createElementNS(SVG_NS, "svg");
  const attrs = { xmlns: SVG_NS, width: String(size), height: String(size), viewBox: "0 0 24 24", fill, stroke: "currentColor", "stroke-width": String(strokeWidth), "stroke-linecap": "round", "stroke-linejoin": "round", class: `icon icon-${name} ${className}`.trim() };
  for (const [key, value] of Object.entries(attrs)) svg.setAttribute(key, value);
  if (label) svg.setAttribute("aria-label", label); else svg.setAttribute("aria-hidden", "true");
  for (const [tag, props] of nodes) {
    const child = document.createElementNS(SVG_NS, tag);
    for (const [key, value] of Object.entries(props)) child.setAttribute(key, value);
    svg.appendChild(child);
  }
  return svg;
}