1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
require "pro_tacts/admin/phlex"
module ProTacts
module Admin
# Lucide icons, inlined: the set docs/DESIGN.md's icon rule names.
# The path data below is lucide-static's own (v0.548.0, ISC
# license), copied verbatim rather than redrawn. A new glyph lands
# the same way — named in the registry, its shapes verbatim, this
# comment's version moved with it.
class Icon < Phlex::SVG
# @rbs @name: Symbol
# @rbs @size: Integer
# One glyph's shapes, each an element name and its attributes,
# verbatim from the lucide-static SVG's own children: x, the
# remove and clear controls' two strokes; calendar, the birthday row's
# picker; the import row's verdict, a circle either way and
# a check in it when the row is in the book;
# chevron-down, the account menu's opening direction;
# search, the glyph on the header's search button; house,
# the phone header's way home from the search page; and image,
# a group tag's mark that the group has a photo. A tag
# per shape rather than a bare list of path data, because
# calendar's frame is a rect and redrawing it as a path would
# be this file copying something other than what Lucide ships.
GLYPHS = {
x: [
[:path, {d: "M18 6 6 18"}],
[:path, {d: "m6 6 12 12"}],
],
calendar: [
[:path, {d: "M8 2v4"}],
[:path, {d: "M16 2v4"}],
[:rect, {width: 18, height: 18, x: 3, y: 4, rx: 2}],
[:path, {d: "M3 10h18"}],
],
circle: [
[:circle, {cx: 12, cy: 12, r: 10}],
],
circle_check: [
[:circle, {cx: 12, cy: 12, r: 10}],
[:path, {d: "m9 12 2 2 4-4"}],
],
chevron_down: [
[:path, {d: "m6 9 6 6 6-6"}],
],
search: [
[:path, {d: "m21 21-4.34-4.34"}],
[:circle, {cx: 11, cy: 11, r: 8}],
],
image: [
[:rect, {width: 18, height: 18, x: 3, y: 3, rx: 2, ry: 2}],
[:circle, {cx: 9, cy: 9, r: 2}],
[:path, {d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"}],
],
house: [
[:path, {d: "M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"}],
[:path, {d: "M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"}],
],
} #: Hash[Symbol, Array[[Symbol, Hash[Symbol, untyped]]]]
#: (Symbol name, ?size: Integer) -> void
def initialize(name, size: 16)
@name = name
@size = size
end
def view_template
# viewBox is camelCase on purpose: SVG attribute names are
# case-sensitive, and Phlex's underscore-to-dash convention
# would render view_box as view-box, which no browser reads.
svg(viewBox: "0 0 24 24", width: @size, height: @size, fill: :none,
stroke: "currentColor", stroke_width: 2, stroke_linecap: "round",
stroke_linejoin: "round", aria_hidden: true) do
GLYPHS.fetch(@name).each do |tag, attributes|
public_send(tag, **attributes)
end
end
end
end
end
end