Skip to content

Commit f069a8a

Browse files
committed
Use icons for actions
1 parent 4e951a5 commit f069a8a

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-7
lines changed

assets/tailwind.config.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// https://www.phoenixdiff.org/compare/1.6.15...1.7.0
33

44
const plugin = require('tailwindcss/plugin');
5+
const fs = require('fs');
6+
const path = require('path');
57

68
module.exports = {
79
content: [
@@ -43,5 +45,61 @@ module.exports = {
4345
'.phx-change-loading &',
4446
]),
4547
),
48+
49+
// Embeds Heroicons (https://heroicons.com) into your app.css bundle
50+
// See your `CoreComponents.icon/1` for more information.
51+
//
52+
plugin(function ({ matchComponents, theme }) {
53+
const iconsDir = path.join(__dirname, '../deps/heroicons/optimized');
54+
const values = {};
55+
const icons = [
56+
['', '/24/outline'],
57+
['-solid', '/24/solid'],
58+
['-mini', '/20/solid'],
59+
['-micro', '/16/solid'],
60+
];
61+
icons.forEach(([suffix, dir]) => {
62+
fs.readdirSync(path.join(iconsDir, dir)).forEach((file) => {
63+
const name = path.basename(file, '.svg') + suffix;
64+
values[name] = { name, fullPath: path.join(iconsDir, dir, file) };
65+
});
66+
});
67+
matchComponents(
68+
{
69+
hero: ({ name, fullPath }) => {
70+
const content = fs
71+
.readFileSync(fullPath)
72+
.toString()
73+
.replace(/\r?\n|\r/g, '');
74+
75+
const getSize = () => {
76+
if (name.endsWith('-mini')) {
77+
return theme('spacing.5');
78+
}
79+
if (name.endsWith('-micro')) {
80+
return theme('spacing.4');
81+
}
82+
83+
return theme('spacing.6');
84+
};
85+
86+
const size = getSize();
87+
88+
return {
89+
[`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
90+
'-webkit-mask': `var(--hero-${name})`,
91+
mask: `var(--hero-${name})`,
92+
'mask-repeat': 'no-repeat',
93+
'background-color': 'currentColor',
94+
'vertical-align': 'middle',
95+
display: 'inline-block',
96+
width: size,
97+
height: size,
98+
};
99+
},
100+
},
101+
{ values },
102+
);
103+
}),
46104
],
47105
};

lib/ex_rss_web.ex

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,8 @@ defmodule ExRssWeb do
113113
quote do
114114
# HTML escaping functionality
115115
import Phoenix.HTML
116-
# TODO
117-
# Phoenix 1.7 would also generate `import ExRssWeb.CoreComponents`. I did
118-
# not add this import to keep the initial migration to `LiveView` small.
119-
# Translation
116+
117+
import ExRssWeb.CoreComponents
120118
import ExRssWeb.Gettext
121119

122120
# Shortcut for generating JS commands
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
defmodule ExRssWeb.CoreComponents do
2+
use Phoenix.Component
3+
4+
@doc """
5+
Renders a [Heroicon](https://heroicons.com).
6+
7+
Heroicons come in three styles – outline, solid, and mini.
8+
By default, the outline style is used, but solid and mini may
9+
be applied by using the `-solid` and `-mini` suffix.
10+
11+
You can customize the size and colors of the icons by setting
12+
width, height, and background color classes.
13+
14+
Icons are extracted from the `deps/heroicons` directory and bundled within
15+
your compiled app.css by the plugin in your `assets/tailwind.config.js`.
16+
17+
## Examples
18+
19+
<.icon name="hero-x-mark-solid" />
20+
<.icon name="hero-arrow-path" class="ml-1 w-3 h-3 animate-spin" />
21+
"""
22+
attr :name, :string, required: true
23+
attr :class, :string, default: nil
24+
25+
def icon(%{name: "hero-" <> _} = assigns) do
26+
~H"""
27+
<span class={[@name, @class]} />
28+
"""
29+
end
30+
end

lib/ex_rss_web/feed_live/index.html.heex

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
</div>
1010

1111
<div class="md:shrink-0 flex self-start mt-1 ml-auto space-x-4">
12-
<a target="_blank" aria-label={"View entry #{@oldest_unread_entry.title}"}>View</a>
13-
<button aria-label="Mark as read">Mark as read</button>
12+
<a href={@oldest_unread_entry.url} target="_blank" aria-label={"View entry #{@oldest_unread_entry.title}"}>
13+
<.icon name="hero-arrow-top-right-on-square-solid" />
14+
</a>
15+
<button aria-label="Mark as read">
16+
<.icon name="hero-check-circle-solid" />
17+
</button>
1418
</div>
1519
</li>
1620
</ul>

mix.exs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ defmodule ExRss.Mixfile do
5151
{:timex, "~> 3.1"},
5252
{:bcrypt_elixir, "~> 3.0"},
5353
{:mix_test_watch, "~> 1.0", only: :dev, runtime: false},
54-
{:mox, "~> 1.1", only: [:dev, :test]}
54+
{:mox, "~> 1.1", only: [:dev, :test]},
55+
{:heroicons,
56+
github: "tailwindlabs/heroicons",
57+
tag: "v2.2.0",
58+
sparse: "optimized",
59+
app: false,
60+
compile: false,
61+
depth: 1}
5562
]
5663
end
5764

mix.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"floki": {:hex, :floki, "0.36.3", "1102f93b16a55bc5383b85ae3ec470f82dee056eaeff9195e8afdf0ef2a43c30", [:mix], [], "hexpm", "fe0158bff509e407735f6d40b3ee0d7deb47f3f3ee7c6c182ad28599f9f6b27a"},
2121
"gettext": {:hex, :gettext, "0.26.1", "38e14ea5dcf962d1fc9f361b63ea07c0ce715a8ef1f9e82d3dfb8e67e0416715", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "01ce56f188b9dc28780a52783d6529ad2bc7124f9744e571e1ee4ea88bf08734"},
2222
"hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
23+
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "0435d4ca364a608cc75e2f8683d374e55abbae26", [tag: "v2.2.0", sparse: "optimized"]},
2324
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
2425
"httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"},
2526
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},

0 commit comments

Comments
 (0)