glimmer-dsl-web-icons 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +248 -0
- data/lib/glimmer/dsl/web/icons/heroicons.rb +1323 -0
- data/lib/glimmer/dsl/web/icons/icon.rb +80 -0
- data/lib/glimmer/dsl/web/icons/lucide.rb +1818 -0
- data/lib/glimmer/dsl/web/icons/phosphor.rb +9117 -0
- data/lib/glimmer/dsl/web/icons/registry.rb +84 -0
- data/lib/glimmer/dsl/web/icons/version.rb +9 -0
- data/lib/glimmer-dsl-web-icons.rb +12 -0
- metadata +86 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3c1ec4d7a84f74fc29a957d09695b31aded05539f4961c66e682e644726c921c
|
|
4
|
+
data.tar.gz: 37defa08db233e497232f04935599063885d0730a58d39f67284905b4ad6c21c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 67d3ad8b95772f514e9bbe02a8c16c13b42e58f275febb5540d46258e247571b9196368a21ce4ccea1437a5c6771781491a66ccb270c345810cf571e4f3d790b
|
|
7
|
+
data.tar.gz: be618afd010463c11818defed8000de4d45a50c6a14b87f9dd748e0f9ce6ea724a2ec32ba336c46739f20f9115b8cda4606e3e0b477e528310777ba8926da673
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Allan Ientz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# glimmer-dsl-web-icons
|
|
2
|
+
|
|
3
|
+
Icon library support for [glimmer-dsl-web](https://github.com/AndyObtiva/glimmer-dsl-web)
|
|
4
|
+
projects. Ships [Lucide](https://lucide.dev), [Heroicons](https://heroicons.com),
|
|
5
|
+
and [Phosphor](https://phosphoricons.com) today.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
glimmer-dsl-web has no built-in icon story: every project doing real UI work
|
|
10
|
+
ends up hand-copying SVG path data into its own components. This gem fills
|
|
11
|
+
that gap by shipping icon data from popular icon libraries in
|
|
12
|
+
glimmer-dsl-web's own native format -- so an icon becomes a normal DSL call
|
|
13
|
+
instead of a pile of hand-maintained SVG markup.
|
|
14
|
+
|
|
15
|
+
## Status
|
|
16
|
+
|
|
17
|
+
Early. Three libraries ship today, deliberately chosen (after Lucide) to
|
|
18
|
+
stress-test the design against real differences rather than guessed ones:
|
|
19
|
+
|
|
20
|
+
- `:lucide` -- one style, stroke-based.
|
|
21
|
+
- `:heroicons_outline`, `:heroicons_solid`, `:heroicons_mini`,
|
|
22
|
+
`:heroicons_micro` -- Heroicons' own four style/size variants (24px
|
|
23
|
+
stroke, 24px fill, 20px fill, 16px fill). Each is a real, separately
|
|
24
|
+
designed icon set, not a resize.
|
|
25
|
+
- `:phosphor_thin`, `:phosphor_light`, `:phosphor_regular`, `:phosphor_bold`,
|
|
26
|
+
`:phosphor_fill`, `:phosphor_duotone` -- Phosphor's six "weights". Unlike
|
|
27
|
+
Heroicons, all six share one identical root `<svg>` (fill-based, same
|
|
28
|
+
viewBox) -- still verified per weight rather than assumed, since nothing
|
|
29
|
+
guarantees a future release keeps it that way, but it turned out not to
|
|
30
|
+
be where Phosphor's real difference is.
|
|
31
|
+
|
|
32
|
+
Each of these was added for a specific reason, not just to pad the list:
|
|
33
|
+
|
|
34
|
+
- **Heroicons** showed the root `<svg>` attributes (fill/stroke/viewBox)
|
|
35
|
+
aren't universal -- an earlier version hardcoded Lucide's stroke-based
|
|
36
|
+
convention directly into the `Icon` component, and Heroicons' solid
|
|
37
|
+
styles (`fill: currentColor`, no stroke at all) broke that assumption.
|
|
38
|
+
Fixed by moving those attrs into the registry, per library --
|
|
39
|
+
`register(library, icons, attrs: {...})` -- see `registry.rb`.
|
|
40
|
+
- **Phosphor** was chosen specifically to test *multi-color* icon support,
|
|
41
|
+
flagged from the start as an unvalidated gap (single-color libraries
|
|
42
|
+
don't exercise it). Its `duotone` weight turned out to need **no design
|
|
43
|
+
change at all**: the two-tone effect is just two `<path>`s sharing one
|
|
44
|
+
`fill: currentColor`, where the background layer carries its own
|
|
45
|
+
`opacity="0.2"` -- a per-*shape* attribute, which this gem's
|
|
46
|
+
`[[tag, attrs], ...]` format already carried through generically from
|
|
47
|
+
day one (the same mechanism that already handled Heroicons' per-path
|
|
48
|
+
`stroke-linecap`). Confirmed against all 1512 duotone icons, not
|
|
49
|
+
assumed from one example -- see `generate/phosphor.rb`.
|
|
50
|
+
|
|
51
|
+
The public API (`library:` option, one data file per library that
|
|
52
|
+
self-registers with the registry, `attrs:` for whatever a library's icons
|
|
53
|
+
share at the root) has now absorbed two real design pressures without
|
|
54
|
+
breaking callers of the first library added under it.
|
|
55
|
+
|
|
56
|
+
## Roadmap: planned libraries
|
|
57
|
+
|
|
58
|
+
Next additions are meant to match the icon-library coverage of
|
|
59
|
+
[`rails_icons`](https://github.com/Rails-Designer/rails_icons) /
|
|
60
|
+
[`Rails-Designer/icons`](https://github.com/Rails-Designer/icons) -- the
|
|
61
|
+
prior art this gem's two-layer shape (data registry + thin rendering
|
|
62
|
+
component) is deliberately modeled on. `rails_icons` supports 12 libraries
|
|
63
|
+
total; the full list, with the 3 already shipped checked off:
|
|
64
|
+
|
|
65
|
+
- [x] [Lucide](https://lucide.dev) (1,799 icons)
|
|
66
|
+
- [x] [Heroicons](https://heroicons.com) (4 variants, 324/324/324/316 icons)
|
|
67
|
+
- [x] [Phosphor](https://phosphoricons.com) (6 weights, 1,512 icons each)
|
|
68
|
+
- [ ] [Tabler](https://tabler.io/icons) (~5,700 icons)
|
|
69
|
+
- [ ] [Hugeicons](https://hugeicons.com) (~4,600 icons)
|
|
70
|
+
- [ ] [Boxicons](https://boxicons.com) (~1,600 icons)
|
|
71
|
+
- [ ] [Radix Icons](https://www.radix-ui.com/icons) (~300 icons)
|
|
72
|
+
- [ ] [Feather](https://feathericons.com) (~280 icons)
|
|
73
|
+
- [ ] [Linear Icons](https://linear.app) (~170 icons)
|
|
74
|
+
- [ ] Flags (~540 icons)
|
|
75
|
+
- [ ] Weather icons (~215 icons)
|
|
76
|
+
- [ ] SidekickIcons (~49 icons, complements Heroicons)
|
|
77
|
+
|
|
78
|
+
Not committed to this exact order, and not committed to shipping all nine
|
|
79
|
+
remaining -- each one only earns a slot once it's actually confirmed against its real
|
|
80
|
+
source (the way Lucide/Heroicons/Phosphor were), and only kept if it either
|
|
81
|
+
works with the current design as-is or teaches it something new, the same
|
|
82
|
+
bar Heroicons and Phosphor were held to above. Tabler and Feather are
|
|
83
|
+
stroke-based like Lucide and are expected to need no design changes; Flags
|
|
84
|
+
and Weather are the more likely candidates to surface something new (Flags
|
|
85
|
+
in particular may not be simple monochrome shapes).
|
|
86
|
+
|
|
87
|
+
## Installing in a Rails app
|
|
88
|
+
|
|
89
|
+
This assumes your app already has glimmer-dsl-web's Opal build pipeline set
|
|
90
|
+
up (i.e. you followed glimmer-dsl-web's own
|
|
91
|
+
[Rails setup guide](https://github.com/AndyObtiva/glimmer-dsl-web/blob/master/docs/setup/rails_7_8_build_pipeline.md)
|
|
92
|
+
and have a working `config/initializers/opal.rb`).
|
|
93
|
+
|
|
94
|
+
1. Add to your `Gemfile` and `bundle install`:
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
gem 'glimmer-dsl-web-icons'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
2. **Add it to `config.opal.use_gems` in `config/initializers/opal.rb`.**
|
|
101
|
+
This step is easy to miss and the gem will silently fail to compile into
|
|
102
|
+
your browser bundle without it:
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
config.opal.use_gems = %w[glimmer-dsl-web glimmer-dsl-web-icons]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Why: Opal compiles your `app/assets/opal` code to JavaScript *ahead of
|
|
109
|
+
time*, so there's no Ruby process in the browser to resolve a `require`
|
|
110
|
+
later the way a normal Rails `Gemfile` gem would be. `use_gems` is the
|
|
111
|
+
explicit whitelist that tells the Opal build step which gems' Ruby
|
|
112
|
+
source to scan and compile into that bundle. Being in your `Gemfile` only
|
|
113
|
+
makes a gem available to server-side Ruby -- any gem your Opal-side code
|
|
114
|
+
`require`s has to *also* be listed here, and glimmer-dsl-web's own setup
|
|
115
|
+
guide only shows this line with itself in the array, so it's worth
|
|
116
|
+
calling out explicitly rather than leaving people to hit the failure and
|
|
117
|
+
guess.
|
|
118
|
+
|
|
119
|
+
3. In whichever Opal file needs icons, require this gem plus the library
|
|
120
|
+
data file(s) you want (each library is opt-in, so nothing loads that you
|
|
121
|
+
don't ask for):
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
require 'glimmer-dsl-web-icons'
|
|
125
|
+
require 'glimmer/dsl/web/icons/lucide'
|
|
126
|
+
require 'glimmer/dsl/web/icons/heroicons' # if you want Heroicons too
|
|
127
|
+
require 'glimmer/dsl/web/icons/phosphor' # if you want Phosphor too
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Note: each data file above compiles its *entire* icon set into your
|
|
131
|
+
Opal bundle once required -- Lucide alone is ~1800 icons, Phosphor's
|
|
132
|
+
six weights ~9000 between them. There's no way yet to require only the
|
|
133
|
+
handful of icons you actually use (that would mean generating one file
|
|
134
|
+
per icon instead of one per library) -- a real tradeoff, tracked as a
|
|
135
|
+
possible future change rather than solved here.
|
|
136
|
+
|
|
137
|
+
## Usage
|
|
138
|
+
|
|
139
|
+
Every icon, from any library, is rendered by the same `icon` call --
|
|
140
|
+
there's no per-library Ruby API, only different `library:` values (and
|
|
141
|
+
different icon names within each):
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
icon(name, library: :lucide, size: 24)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
| Option | Required | Default | Meaning |
|
|
148
|
+
| --- | --- | --- | --- |
|
|
149
|
+
| `name` | yes | -- | Icon name string, e.g. `'circle-check'`. Can be passed positionally (`icon('circle-check', ...)`, mirroring shadcn_glimmer's `ShButton`/`ShIcon` convention) or as `name:` -- both are equivalent. |
|
|
150
|
+
| `library` | no | `:lucide` | Which registered library/variant to look the name up in (see per-library tables below). Its data file must be `require`d first (Installing, step 3), or `Icons.lookup` raises `UnknownLibraryError`. |
|
|
151
|
+
| `size` | no | `24` | Sets both `width` and `height` on the root `<svg>`, in pixels. The only option that works identically across every library. |
|
|
152
|
+
|
|
153
|
+
An unrecognized icon name raises `Icons::UnknownIconError` rather than
|
|
154
|
+
rendering nothing, so a typo fails loudly instead of silently.
|
|
155
|
+
|
|
156
|
+
Root `<svg>` attributes (fill/stroke/stroke-width/viewBox) are fixed **per
|
|
157
|
+
library/variant**, not configurable per call -- they come entirely from
|
|
158
|
+
whichever `library:` value you pick. There's no `attrs:`/`stroke_width:`
|
|
159
|
+
override at the call site today; if you need a different stroke width than
|
|
160
|
+
a library's default, that's a gap, not a hidden option.
|
|
161
|
+
|
|
162
|
+
### Lucide -- `:lucide` (default)
|
|
163
|
+
|
|
164
|
+
1,799 icons, one style, stroke-based.
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
icon('circle-check', library: :lucide, size: 20)
|
|
168
|
+
icon('circle-check', size: 20) # library: :lucide is the default, can be omitted
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Root `<svg>` attrs: `viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"`.
|
|
172
|
+
|
|
173
|
+
### Heroicons -- `:heroicons_outline`, `:heroicons_solid`, `:heroicons_mini`, `:heroicons_micro`
|
|
174
|
+
|
|
175
|
+
4 independently-designed style/size variants. The variant *is* the
|
|
176
|
+
`library:` value -- there's no separate `style:`/`variant:` option. 324
|
|
177
|
+
icons per variant (316 for `micro` -- Heroicons ships a few fewer icons at
|
|
178
|
+
that size).
|
|
179
|
+
|
|
180
|
+
```ruby
|
|
181
|
+
icon('heart', library: :heroicons_outline) # 24px, stroke-based
|
|
182
|
+
icon('heart', library: :heroicons_solid) # 24px, fill-based
|
|
183
|
+
icon('heart', library: :heroicons_mini) # 20px, fill-based
|
|
184
|
+
icon('heart', library: :heroicons_micro) # 16px, fill-based
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
| `library:` | viewBox | fill | stroke |
|
|
188
|
+
| --- | --- | --- | --- |
|
|
189
|
+
| `:heroicons_outline` | `0 0 24 24` | `none` | `currentColor`, `stroke-width: 1.5` |
|
|
190
|
+
| `:heroicons_solid` | `0 0 24 24` | `currentColor` | none |
|
|
191
|
+
| `:heroicons_mini` | `0 0 20 20` | `currentColor` | none |
|
|
192
|
+
| `:heroicons_micro` | `0 0 16 16` | `currentColor` | none |
|
|
193
|
+
|
|
194
|
+
### Phosphor -- `:phosphor_thin`, `:phosphor_light`, `:phosphor_regular`, `:phosphor_bold`, `:phosphor_fill`, `:phosphor_duotone`
|
|
195
|
+
|
|
196
|
+
6 weights, selected via `library:` the same way as Heroicons' variants.
|
|
197
|
+
1,512 icons per weight.
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
icon('heart', library: :phosphor_thin)
|
|
201
|
+
icon('heart', library: :phosphor_light)
|
|
202
|
+
icon('heart', library: :phosphor_regular)
|
|
203
|
+
icon('heart', library: :phosphor_bold)
|
|
204
|
+
icon('heart', library: :phosphor_fill) # flat solid
|
|
205
|
+
icon('heart', library: :phosphor_duotone) # two-tone: light bg shape + solid fg shape
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
All six weights share identical root `<svg>` attrs: `viewBox="0 0 256 256" fill="currentColor"`.
|
|
209
|
+
The thin/light/regular/bold difference is baked into each icon's own path
|
|
210
|
+
data (there's no adjustable `stroke-width` the way Lucide has one), and
|
|
211
|
+
`duotone`'s two-tone look comes from two overlapping shapes at different
|
|
212
|
+
opacities within the icon data itself -- nothing you pass at the call site
|
|
213
|
+
changes it.
|
|
214
|
+
|
|
215
|
+
## Development
|
|
216
|
+
|
|
217
|
+
No Bundler required to hack on this gem -- it's pure Ruby with only
|
|
218
|
+
`rake`/`minitest` as dev dependencies (both ship with a standard Ruby
|
|
219
|
+
install). Run the test suite with:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
rake test
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`generate/lucide.rb`, `generate/heroicons.rb`, and `generate/phosphor.rb`
|
|
226
|
+
are dev-only scripts (not shipped in the gem) that regenerate their
|
|
227
|
+
respective `lib/glimmer/dsl/web/icons/*.rb` files from a local
|
|
228
|
+
`npm install lucide` / `npm install heroicons` /
|
|
229
|
+
`npm install @phosphor-icons/core` checkout under `references/` -- see
|
|
230
|
+
each script's header comment for how to re-sync when a library releases
|
|
231
|
+
new icons.
|
|
232
|
+
|
|
233
|
+
## Adding another library
|
|
234
|
+
|
|
235
|
+
Each library is one file under `lib/glimmer/dsl/web/icons/` that builds an
|
|
236
|
+
`{"icon-name" => [[tag, attrs], ...]}` Hash and calls
|
|
237
|
+
`Glimmer::DSL::Web::Icons.register(:your_library, that_hash, attrs: {...})`,
|
|
238
|
+
where `attrs:` is whatever root `<svg>` attributes every icon in that
|
|
239
|
+
library shares (see `registry.rb`). Whether a new library needs one
|
|
240
|
+
registration or several (the way Heroicons and Phosphor both needed
|
|
241
|
+
several) depends on whether it actually ships multiple
|
|
242
|
+
independently-designed styles -- confirm that against the library's real
|
|
243
|
+
source rather than assuming either way, the same way each of these three
|
|
244
|
+
was. See "Roadmap" above for the specific libraries planned next.
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
MIT.
|