84 lines
5.0 KiB
C#
84 lines
5.0 KiB
C#
using System.Collections.Frozen;
|
|
|
|
namespace Elternbeirat.Web.Shared;
|
|
|
|
/// <summary>
|
|
/// The fixed set of line icons the site can show, keyed by name.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The icons are inlined as SVG markup instead of being loaded from an icon font or
|
|
/// a CDN: the site loads nothing from third-party hosts (see <c>docs/recht.md</c>),
|
|
/// and inline SVG needs no extra request and inherits the text colour.
|
|
/// <para>
|
|
/// Source: Lucide (<c>lucide.dev</c>), ISC license; the icons derived from
|
|
/// Feather (<c>calendar</c>, <c>clock</c>, <c>download</c>,
|
|
/// <c>external-link</c>, <c>help-circle</c>, <c>info</c>, <c>arrow-right</c>)
|
|
/// are MIT, Copyright (c) 2013-present Cole Bemis. Both licenses only ask that
|
|
/// the notice travels with the copy, which this comment does. Only the inner
|
|
/// elements are stored; <see cref="Icon"/> supplies the shared
|
|
/// <c><svg></c> wrapper (24x24 view box, 2px round stroke).
|
|
/// </para>
|
|
/// <para>
|
|
/// Lucide renamed <c>help-circle</c> to <c>circle-question-mark</c>; the old
|
|
/// name is kept here because it is the one the design work refers to.
|
|
/// </para>
|
|
/// </remarks>
|
|
/// <seealso cref="Icon"/>
|
|
public static class IconSet
|
|
{
|
|
/// <summary>
|
|
/// Inner SVG markup per icon name. Ordinal keys: names are code identifiers,
|
|
/// not visitor text, so <c>Calendar</c> is deliberately not <c>calendar</c>.
|
|
/// </summary>
|
|
private static readonly FrozenDictionary<string, string> Icons =
|
|
new Dictionary<string, string>
|
|
{
|
|
["calendar"] =
|
|
"""<path d="M8 2v3"/><path d="M16 2v3"/><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/>""",
|
|
["calendar-plus"] =
|
|
"""<path d="M16 18h6"/><path d="M16 2v3"/><path d="M19 15v6"/><path d="M21 11.5V5a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h8.3"/><path d="M3 9h18"/><path d="M8 2v3"/>""",
|
|
["clock"] =
|
|
"""<circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/>""",
|
|
["map-pin"] =
|
|
"""<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>""",
|
|
["file-text"] =
|
|
"""<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"/>""",
|
|
["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"/>""",
|
|
["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"/>""",
|
|
["users"] =
|
|
"""<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><path d="M16 3.128a4 4 0 0 1 0 7.744"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><circle cx="9" cy="7" r="4"/>""",
|
|
["heart-handshake"] =
|
|
"""<path d="M19.414 14.414C21 12.828 22 11.5 22 9.5a5.5 5.5 0 0 0-9.591-3.676.6.6 0 0 1-.818.001A5.5 5.5 0 0 0 2 9.5c0 2.3 1.5 4 3 5.5l5.535 5.362a2 2 0 0 0 2.879.052 2.12 2.12 0 0 0-.004-3 2.124 2.124 0 1 0 3-3 2.124 2.124 0 0 0 3.004 0 2 2 0 0 0 0-2.828l-1.881-1.882a2.41 2.41 0 0 0-3.409 0l-1.71 1.71a2 2 0 0 1-2.828 0 2 2 0 0 1 0-2.828l2.823-2.762"/>""",
|
|
["help-circle"] =
|
|
"""<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"/>""",
|
|
["newspaper"] =
|
|
"""<path d="M15 18h-5"/><path d="M18 14h-8"/><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2"/><rect width="8" height="4" x="10" y="6" rx="1"/>""",
|
|
["arrow-right"] =
|
|
"""<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>""",
|
|
["external-link"] =
|
|
"""<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>""",
|
|
["info"] =
|
|
"""<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>""",
|
|
}.ToFrozenDictionary(StringComparer.Ordinal);
|
|
|
|
/// <summary>
|
|
/// Looks up the inner SVG markup of an icon.
|
|
/// </summary>
|
|
/// <param name="name">
|
|
/// The icon name, e.g. <c>calendar</c> or <c>map-pin</c>. Case-sensitive.
|
|
/// </param>
|
|
/// <returns>
|
|
/// The SVG child elements (paths, circles, rects) to place inside an
|
|
/// <c><svg></c>, or <see langword="null"/> if <paramref name="name"/> is
|
|
/// <see langword="null"/> or not part of the set.
|
|
/// </returns>
|
|
/// <remarks>
|
|
/// An unknown name yields <see langword="null"/> rather than an exception, so a
|
|
/// typo costs a missing decoration, never a broken page.
|
|
/// </remarks>
|
|
public static string? Find(string? name) =>
|
|
name is null ? null : Icons.GetValueOrDefault(name);
|
|
}
|