This is used to generate the SVG icons for Bits in the elm code.
The changes / process is kind of janky. Here's what you gotta do:
- Download all the icons as svgs from figma
- This will create zip folder with all the icons in their own svg file
-
npm run build
this. -
Run
bin/svg2elm ~/Downloads/icons/* | pbcopy
(on a mac) -
This will generate the
Bits.Icon.CodeGen
module
- Paste your output into the brilliant repo
-
Now, you'll need corresponding functions and exports in
Bits.Icon
. You can generate those by going tocli.ts
in this repo and changinggenerateModule
togenerateExports
andgenerateFunctions
respectively. -
Go back to step 2! ie. re build, re run, re copy, paste in the appropriate place
Generates Elm modules out of SVG files. Comes with a CLI tool and a JavaScript API to build bundler plugins.
Using Parcel? Check out parcel-plugin-elm-svg.
You can install svg2elm
from npm:
$ npm install -g svg2elm
Let's say we have a chevron icon that we want to embed in our Elm app:
$ cat chevron.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<line x1="1" y1="1" x2="50" y2="50" stroke-linecap="round" />
<line x1="50" y1="50" x2="1" y2="99" stroke-linecap="round" />
</svg>
Using svg2elm
we can generate an Elm module out of it. Let's call ours Acme.Icons
:
$ svg2elm --module Acme.Icons chevron.svg > Acme/Icons.elm
module Acme.Icons exposing (..)
import Svg
import VirtualDom exposing (Attribute, attribute)
chevron : List (Attribute msg) -> Svg.Svg msg
chevron attrs = Svg.node "svg" ([attribute "xmlns" "http://www.w3.org/2000/svg", attribute "viewBox" "0 0 100 100"] ++ attrs) [ Svg.node "line" ([attribute "x1" "1", attribute "y1" "1", attribute "x2" "50", attribute "y2" "50", attribute "stroke-linecap" "round"]) [], Svg.node "line" ([attribute "x1" "50", attribute "y1" "50", attribute "x2" "1", attribute "y2" "99", attribute "stroke-linecap" "round"]) []]
We are now ready to embed the icon in our app! Since the generated function returns an Svg node, we can use it like any other element:
import Acme.Icons exposing (chevron)
...
nextPage =
button []
[ text "Next Page"
, chevron []
]
Note that the generated function takes a List of Attributes:
chevron : List (Attribute msg) -> Svg.Svg msg
This allows us to tweak our icons in a per usage basis. For example, if we wanted to point our chevron to the left, we could do the following:
previousPage =
button []
[ text "Previous Page"
, chevron [ transform "rotate(180)" ]
]
Similarly, we could change the size, colors, stroke width, etc.
...
, chevron [ width "30", stroke "blue", strokeWidth "2" ]
...
Attributes are appended to the top SVG node. This means that you can only override those set at that level. This is usually not a problem since child nodes inherit parent attributes. However, you might have to tweak your SVG to fit your needs.
You likely want to generate a module with all your app icons. You can do this by passing multiple files to svg2elm
:
$ svg2elm --module Acme.Icons icons/chevron.svg icons/user.svg
...or you can use globs:
$ svg2elm --module Acme.Icons icons/*.svg
A function will be generated for each SVG file.
If you're using the awesome mdgriffith/elm-ui, you have to use Element.html to turn your Svg node into an Element.
nextPage =
button []
[ text "Next Page"
, chevron [] |> html
]
This package also exposes a JavaScript API that can be used to fit svg2elm
into any build process.
It's just three functions: reference.
At PINATA, we have been using SVGR for years to load our icons as React components. This project aims to bring the same experience to the world of Elm.
BSD-3-Clause. See LICENSE file.
Thanks to rnons for building elm-svg-parser and Garados007 for making it work with Elm 0.19.
Built by Piotr Brzeziński and Agustín Zubiaga at PINATA.
♥︎