├── .gitignore
├── .npmignore
├── README.md
├── dev
├── basic.vue
├── font-compatible.vue
├── icon-stack.vue
└── webpack.config.coffee
├── karma.conf.coffee
├── package.json
├── src
├── icon-font-compatible.coffee
├── icon-loader.coffee
├── icon-stack.coffee
├── icon.vue
└── process-fonts.coffee
└── test
└── icon.coffee
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.sublime-project
3 | *.sublime-workspace
4 | npm-debug.log
5 | build/bundle.js
6 | dev/index.js
7 | static
8 | *.js
9 | icons/
10 | .vscode
11 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.sublime-project
3 | *.sublime-workspace
4 | npm-debug.log
5 | dev/index.js
6 | static
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DEPRECATED see [cerijs](https://github.com/cerijs) and [ceri-icon](https://github.com/ceri-comps/ceri-icon)
2 |
3 | # vue-icons
4 |
5 | webpack based - load only what you need - svg inline icons.
6 |
7 | comes with (and prefixes):
8 | - [Font Awesome](https://fortawesome.github.io/Font-Awesome/icons/) - `fa`
9 | - [Google Material Design Icons](https://design.google.com/icons/) - `material` - spaces in icon names are replaced by `_`, e.g. `material-done_all`.
10 | - [Material Design Icons](https://materialdesignicons.com/) - `mdi`
11 | - [Octicons](https://octicons.github.com/) - `octicon`
12 | - [Open Iconic](https://useiconic.com/open#icons) - `iconic`
13 | - [Glyphicons](http://getbootstrap.com/components/#glyphicons) - `glyphicon`
14 | - [IcoMoon-free](https://icomoon.io/#preview-free) - `im`
15 | - [ratchicons](http://goratchet.com/components/#ratchicons) - `ra` - add `and` for android version `ra-download` -> `ra-and-download`
16 |
17 |
18 | ### [Demo](https://vue-comps.github.io/vue-icons)
19 |
20 | heavily inspired by [vue-awesome](https://github.com/Justineo/vue-awesome).
21 |
22 | # Install
23 |
24 | ```sh
25 | npm install --save-dev vue-icons callback-loader
26 | // vue@1.0
27 | npm install --save-dev vue-icons@1 callback-loader
28 | ```
29 |
30 | ## Usage
31 |
32 | webpack.config:
33 | ```coffee
34 | module:
35 | loaders: [
36 | # your loaders
37 | ]
38 | postLoaders: [
39 | { test: /vue-icons/, loader: "callback-loader"}
40 | ]
41 | callbackLoader:
42 | require("vue-icons/icon-loader")(["fa-thumbs-up"]) # add all the icons you need
43 | ```
44 |
45 | in your component:
46 | ```coffee
47 | components:
48 | "icon": require("vue-icons")
49 | ```
50 | ```html
51 |
52 | ```
53 | see [`dev/`](https://github.com/vue-comps/vue-icons/tree/master/dev) for examples.
54 |
55 | This will load a font-compatible version of the component.
56 | The `height` of the icon will be set to `font-size` and as `svg` render as inline item, it will fit in the middle of `line-height` and responds to `vertical-align` similar as normal glyphs.
57 |
58 | ### ERROR: Module build failed: SyntaxError: 'with' in strict mode
59 | Currently [buble](https://gitlab.com/Rich-Harris/buble) is injecting `strict` mode in all processed js files. The down to ES5 compiled component contains `with`, which is forbidden in `strict` mode.
60 | Buble is used, for example, in rollup, which is used in laravel.
61 |
62 | If you are running in this problem, make sure to exclude this component from processing with buble.
63 |
64 | #### Props
65 | Name | type | default | description
66 | ---:| --- | ---| ---
67 | name | String | - | (required) name of the icon
68 | flip-v | String | - | apply vertical flipping
69 | flip-h | String | - | apply horizontal flipping
70 | offset-x | Number | 0 | move the icon left/right within its borders in percentage (relative to the center)
71 | offset-y | Number | 0 | move the icon up/down within its borders in percentage (relative to the center)
72 | label | String | name | aria-label
73 |
74 | ### Plain icon
75 |
76 | if you don't need the font-compatibility you can also use the plain icon component:
77 | ```coffee
78 | components:
79 | "icon": require("vue-icons/icon")
80 | ```
81 | This has three additional props:
82 |
83 | Name | type | default | description
84 | ---:| --- | ---| ---
85 | size | Number | 16 | height of the icon in px
86 | scale | Number | 1 | size multiplier
87 | hcenter | Boolean | false | sets the height to equal the parentElement and moves the icon to the center
88 |
89 |
90 |
91 | ### Spinners
92 | comes without css, so no spinning included, you can do it manually like this:
93 | ```css
94 | //css
95 | .spin {
96 | animation: spin 1s 0s infinite linear;
97 | }
98 | @keyframes spin {
99 | 0% {
100 | transform: rotate(0deg);
101 | }
102 | 100% {
103 | transform: rotate(360deg);
104 | }
105 | }
106 | ```
107 | ```html
108 |
109 | ```
110 |
111 | ### Icon stack
112 | You can stack icons by using the plain icon and the stack icon component:
113 | ```coffee
114 | components:
115 | "icon": require("vue-icons/icon") # this won't work with the font-compatible version (require("vue-icons"))
116 | "icon-stack": require("vue-icons/icon-stack")
117 | ```
118 | ```html
119 |
120 |
121 |
122 | ```
123 | `offset-x` and `offset-y` on `icon-stack` increase the size of the icon boundaries, so both will stay fully visible.
124 | The normal `icon` will be positioned in the center of the, then larger, boundaries.
125 | ## Changelog
126 | - 2.0.0
127 | added vue 2.0.0 compatibility
128 |
129 | - 1.4.2
130 | added error messages
131 |
132 | - 1.4.1
133 | added ratchicons
134 |
135 | - 1.4.0
136 | changed positioning again (icon-font-compatible with line-height)
137 |
138 | - 1.3.0
139 | added icon stack
140 | added icomoon - `im`
141 | changed `octicons` processing to take the direct svg icons instead of the font
142 |
143 | - 1.2.0
144 | changed flip interface
145 | fixed `glyphicons`
146 | removed `display:inline-block` from default style.
147 | Updated `octicons` - they changed their icon font.
148 |
149 | # Development
150 | Clone repository.
151 | ```sh
152 | npm install
153 | npm run dev
154 | ```
155 | Browse to `http://localhost:8080/`.
156 |
157 | ## License
158 | Copyright (c) 2016 Paul Pflugradt
159 | Licensed under the MIT license.
160 |
--------------------------------------------------------------------------------
/dev/basic.vue:
--------------------------------------------------------------------------------
1 |
2 | .container(style="font-size:12pt")
3 | p fa-glass:
4 | icon(name="fa-glass",ref="fa")
5 | p fa-taxi:
6 | icon(name="fa-taxi")
7 | p fa-cab (alias):
8 | icon(name="fa-cab")
9 | p fa-taxi (flip-h):
10 | icon(name="fa-taxi",flip-h,ref="horizontal")
11 | p fa-bullhorn:
12 | icon(name="fa-bullhorn")
13 | p fa-bullhorn (flip-v):
14 | icon(name="fa-bullhorn",flip-v,ref="vertical")
15 | p fa-bullhorn (size=32):
16 | icon(name="fa-bullhorn",:size=32,ref="size")
17 | p fa-bullhorn (scale=2):
18 | icon(name="fa-bullhorn",:scale=2,ref="scale")
19 | p mdi-account-alert:
20 | icon(name="mdi-account-alert",ref="mdi")
21 | p mdi-account-alert (style="color:red"):
22 | icon(style="color: red;" name="mdi-account-alert", ref="color")
23 | p material-build:
24 | icon(name="material-build",ref="material")
25 | p material-build(flip-h and flip-v):
26 | icon(name="material-build", flip-h flip-v ref="flipboth")
27 | p octicon-logo-github:
28 | icon(name="octicon-logo-github",ref="octicon")
29 | p octicon-heart:
30 | icon(name="octicon-heart")
31 | p glyphicon-heart:
32 | icon(name="glyphicon-heart",ref="glyphicon")
33 | p im-IcoMoon:
34 | icon(name="im-IcoMoon",ref="im")
35 | p ra-download:
36 | icon(name="ra-download",ref="ra")
37 | p ra-and-download:
38 | icon(name="ra-and-download")
39 | p iconic-wrench:
40 | icon(name="iconic-wrench",ref="iconic")
41 | | (vertical-align:sub):
42 | icon(name="iconic-wrench" style="vertical-align:sub")
43 | p(style="height:40px;border: 1px solid black") iconic-wrench (height:40px without hcenter):
44 | icon(name="iconic-wrench")
45 | p(style="height:40px;border: 1px solid black; position:relative") iconic-wrench (height:40px with hcenter), don't use hcenter with text
46 | icon(name="iconic-wrench",hcenter,ref="hcenter")
47 | p(style="line-height:40px;border: 1px solid black; position:relative") iconic-wrench (line-height:40px)
48 | icon(name="iconic-wrench")
49 | p glyphicon-heart(offset-x=-20, offset-y=20):
50 | icon(name="glyphicon-heart",ref="offset",:offset-x=-20, :offset-y=20)
51 | a(href="https://github.com/vue-comps/vue-icons/blob/master/dev/basic.vue") source
52 |
53 |
54 |
60 |
--------------------------------------------------------------------------------
/dev/font-compatible.vue:
--------------------------------------------------------------------------------
1 |
2 | .container
3 | p fa-glass (style="font-size:20px"):
4 | icon(name="fa-glass" style="font-size:20px" ref="size")
5 | p dont use icon within textflow - same as hcenter with normal icon
6 | div(style="font-size:20px;line-height:40px;border:solid 1px black;position:relative") fa-glass (style="font-size:20px;line-height:40px"):
7 | icon(name="fa-glass" ref="lineHeight")
8 | a(href="https://github.com/vue-comps/vue-icons/blob/master/dev/font-compatible.vue") source
9 |
10 |
11 |
17 |
--------------------------------------------------------------------------------
/dev/icon-stack.vue:
--------------------------------------------------------------------------------
1 |
2 | .container(style="font-size:12pt")
3 | p fa-ban(scale=2,style="color:red") on fa-camera:
4 | icon(name="fa-camera")
5 | icon-stack(name="fa-ban",style="color:red",:scale=2)
6 | p fa-beer on fa-thumbs-up (with offset-x / offset-y and scale):
7 | icon(name="fa-thumbs-up",:offset-x=-30)
8 | icon-stack(name="fa-beer",:offset-x=30,:scale=1.2,:offset-y=-20)
9 | a(href="https://github.com/vue-comps/vue-icons/blob/master/dev/basic.vue") source
10 |
11 |
12 |
19 |
--------------------------------------------------------------------------------
/dev/webpack.config.coffee:
--------------------------------------------------------------------------------
1 | webpack = require "webpack"
2 | module.exports =
3 | module:
4 | loaders: [
5 | { test: /\.vue$/, loader: "vue-loader"}
6 | { test: /\.html$/, loader: "html"}
7 | { test: /\.coffee$/, loader: "coffee-loader"}
8 | ]
9 | postLoaders: [
10 | { test: /icon/, loader: "callback-loader"}
11 | ]
12 | resolve:
13 | extensions: ["",".webpack.js",".web.js",".js",".coffee",".vue"]
14 | callbackLoader:
15 | require("../icon-loader.js")([
16 | "fa-glass"
17 | "fa-cab"
18 | "fa-bullhorn"
19 | "fa-camera"
20 | "fa-ban"
21 | "mdi-account-alert"
22 | "material-build"
23 | "octicon-logo-github"
24 | "octicon-heart"
25 | "iconic-wrench"
26 | "glyphicon-heart"
27 | "fa-thumbs-up"
28 | "fa-beer"
29 | "im-IcoMoon"
30 | "ra-download"
31 | "ra-and-download"
32 | ])
33 |
--------------------------------------------------------------------------------
/karma.conf.coffee:
--------------------------------------------------------------------------------
1 | module.exports = (config) ->
2 | config.set
3 | preprocessors:
4 | "**/*.coffee": ["webpack",'sourcemap']
5 | webpack:
6 | devtool: 'inline-source-map'
7 | resolve:
8 | extensions: ["",".js",".coffee",".vue"]
9 | module:
10 | loaders: [
11 | { test: /\.coffee$/, loader: "coffee-loader" }
12 | { test: /\.vue$/, loader: "vue-loader" }
13 | { test: /\.html$/, loader: "html"}
14 | { test: /\.css$/, loader: "style-loader!css-loader" }
15 | ]
16 | postLoaders: [
17 | { test: /icon/, loader: "callback-loader"}
18 | ]
19 | callbackLoader:
20 | require("./icon-loader.js")([
21 | "fa-glass"
22 | "fa-cab"
23 | "fa-bullhorn"
24 | "fa-camera"
25 | "fa-ban"
26 | "mdi-account-alert"
27 | "material-build"
28 | "octicon-logo-github"
29 | "octicon-heart"
30 | "iconic-wrench"
31 | "glyphicon-heart"
32 | "fa-thumbs-up"
33 | "fa-beer"
34 | "im-IcoMoon"
35 | "ra-download"
36 | "ra-and-download"
37 | ])
38 | webpackMiddleware:
39 | noInfo: true
40 | files: ["test/*.coffee"]
41 | frameworks: ["mocha","chai-dom","chai-spies","chai","vue-component"]
42 | plugins: [
43 | require("karma-chai")
44 | require("karma-chai-dom")
45 | require("karma-chrome-launcher")
46 | require("karma-firefox-launcher")
47 | require("karma-mocha")
48 | require("karma-webpack")
49 | require("karma-sourcemap-loader")
50 | require("karma-spec-reporter")
51 | require("karma-chai-spies")
52 | require("karma-vue-component")
53 | ]
54 | browsers: ["Chromium","Firefox"]
55 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-icons",
3 | "description": "webpack based - load only what you need - svg inline icons",
4 | "version": "2.0.0",
5 | "homepage": "https://github.com/vue-comps",
6 | "author": {
7 | "name": "Paul Pflugradt",
8 | "email": "paul.pflugradt@gmail.com"
9 | },
10 | "license": "MIT",
11 | "main": "icon-font-compatible.js",
12 | "repository": {
13 | "type": "git",
14 | "url": "git://github.com/vue-comps/vue-icons"
15 | },
16 | "engines": {
17 | "node": "*"
18 | },
19 | "dependencies": {
20 | "vue-mixins": "^0.3.2"
21 | },
22 | "peerDependencies": {
23 | "callback-loader": "^0.2.4"
24 | },
25 | "devDependencies": {
26 | "bluebird": "^3.4.6",
27 | "bootstrap": "^3.3.7",
28 | "callback-loader": "^0.2.4",
29 | "chai": "^3.5.0",
30 | "chai-spies": "^0.7.1",
31 | "coffee-loader": "^0.7.2",
32 | "coffee-script": "^1.11.1",
33 | "font-awesome": "^4.6.3",
34 | "gh-pages": "^0.11.0",
35 | "icomoon-free-npm": "0.0.0",
36 | "karma": "^1.3.0",
37 | "karma-chai": "^0.1.0",
38 | "karma-chai-dom": "^1.1.0",
39 | "karma-chai-spies": "^0.1.4",
40 | "karma-chrome-launcher": "^2.0.0",
41 | "karma-firefox-launcher": "^1.0.0",
42 | "karma-mocha": "^1.2.0",
43 | "karma-sourcemap-loader": "^0.3.7",
44 | "karma-spec-reporter": "^0.0.26",
45 | "karma-vue-component": "^2.0.0",
46 | "karma-webpack": "^1.8.0",
47 | "material-design-icons": "^3.0.1",
48 | "mdi": "^1.7.22",
49 | "mocha": "^3.1.1",
50 | "octicons": "^4.4.0",
51 | "open-iconic": "^1.1.1",
52 | "pug": "^2.0.0-beta6",
53 | "ratchet": "git://github.com/twbs/ratchet.git#v2.0.2",
54 | "script-runner": "^0.1.5",
55 | "svgfont2js": "^0.1.2",
56 | "svgo": "^0.7.1",
57 | "vue": "^2.0.1",
58 | "vue-compiler": "^2.0.0",
59 | "vue-dev-server": "^2.0.0",
60 | "vue-html-loader": "^1.2.3",
61 | "vue-loader": "^9.5.1",
62 | "webpack": "^1.13.2"
63 | },
64 | "keywords": [
65 | "icon",
66 | "webpack",
67 | "component",
68 | "vue"
69 | ],
70 | "readmeFilename": "README.md",
71 | "scripts": {
72 | "build:coffee": "coffee --no-header --compile --output . src/icon-loader.coffee src/icon-font-compatible.coffee",
73 | "build:fonts": "coffee ./src/process-fonts.coffee",
74 | "build:vue": "NODE_ENV=production vue-compiler --out . src/*.vue",
75 | "build": "run-npm -p build:*",
76 | "dev": "vue-dev-server",
77 | "watch:coffee": "coffee --no-header --watch --output . src/icon-stack.coffee src/icon-font-compatible.coffee",
78 | "watch:test": "karma start --browsers Chromium --auto-watch --reporters spec",
79 | "watch": "run-npm -p watch:*",
80 | "test": "karma start --single-run",
81 | "preversion": "npm test",
82 | "version": "npm run build && git add .",
83 | "postversion": "git push && git push --tags && npm publish",
84 | "ghpages": "vue-dev-server --static static/ && gh-pages -d static"
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/icon-font-compatible.coffee:
--------------------------------------------------------------------------------
1 | # out: ../icon-font-compatible.js
2 | i = require "./icon"
3 | ifc =
4 | render: i.render
5 | mixins: i.mixins
6 | data: ->
7 | elstyle: null
8 | mounted: ->
9 | @$nextTick ->
10 | @elstyle = window.getComputedStyle(@$el)
11 | @onWindowResize =>
12 | @elstyle = window.getComputedStyle(@$el)
13 | props: {}
14 | computed:
15 | outerWidth: i.computed.innerWidth
16 | innerHeight: ->
17 | if @elstyle
18 | return parseFloat @elstyle.getPropertyValue("font-size").replace("px","")
19 | return null
20 | outerHeight: ->
21 | if @elstyle
22 | lh = @elstyle.getPropertyValue("line-height")
23 | if lh != "normal"
24 | return parseFloat lh.replace("px","")
25 | else
26 | return @innerHeight
27 | return null
28 | widthRatio: -> 1
29 | mergeStyle: -> {height: @outerHeight + "px"}
30 |
31 | for prop in ["name","offsetX","offsetY","flipH","flipV","label","style"]
32 | ifc.props[prop] = i.props[prop]
33 | for c in ["processedName","icon","box","aspect","flipped","heightRatio"]
34 | ifc.computed[c] = i.computed[c]
35 |
36 | module.exports = ifc
37 |
--------------------------------------------------------------------------------
/src/icon-loader.coffee:
--------------------------------------------------------------------------------
1 | # out: ../icon-loader.js
2 |
3 | camelize = (str) -> str.replace /-(\w)/g, (_, c) -> if c then c.toUpperCase() else ''
4 |
5 | convertToText = (obj) ->
6 | string = []
7 | if obj == undefined
8 | return String(obj)
9 | else if (Array.isArray and Array.isArray(obj)) or
10 | Object.prototype.toString.call(obj) == '[object Array]'
11 | for prop in obj
12 | string.push(convertToText(obj[prop]))
13 | return "[" + string.join(",") + "]"
14 | else if typeof(obj) == "function"
15 | string.push(obj.toString())
16 |
17 | else if typeof(obj) == "object" and obj?
18 | for key,val of obj
19 | string.push(key + ": " + convertToText(val))
20 | return "{" + string.join(",") + "}"
21 | else
22 | string.push(JSON.stringify(obj))
23 | return string.join(",")
24 |
25 | module.exports = (icons) ->
26 | return getIcons: ->
27 | allIcons =
28 | fa: require("./icons/fa.json")
29 | glyphicon: require("./icons/glyphicon.json")
30 | material: require("./icons/material.json")
31 | mdi: require("./icons/mdi.json")
32 | octicon: require("./icons/octicon.json")
33 | iconic: require("./icons/iconic.json")
34 | im: require("./icons/im.json")
35 | ra: require("./icons/ra.json")
36 | sets = {}
37 | for iconname in icons
38 | tmp = iconname.split("-")
39 | coll = tmp.shift()
40 | name = tmp.join("-")
41 | if allIcons[coll].aliases[name]
42 | name = allIcons[coll].aliases[name]
43 | icon = allIcons[coll].icons[name]
44 | throw new Error "vue-icons: #{name} not found in icon collection: #{coll}" unless icon
45 | sets[coll] = {a:{},i:{}} unless sets[coll]
46 | cName = camelize(name)
47 | unless sets[coll].i[cName]?
48 | sets[coll].i[cName] = d:icon.d, w:icon.w, h:icon.h
49 | if icon.aliases?
50 | for alias in icon.aliases
51 | sets[coll].a[camelize(alias)] = cName
52 | return """
53 | var sets = #{convertToText(sets)}
54 |
55 | function getIcon(coll, name) {
56 | set = sets[coll]
57 | if (process.env.NODE_ENV !== 'production' && (typeof set === "undefined" || set === null)){
58 | console.warn("vue-icons - icon collection "+coll+" not found, is your webpack set up correctly?")
59 | }
60 | if (set.a[name] != null) {
61 | name = set.a[name]
62 | }
63 | var icon = set.i[name]
64 | if (process.env.NODE_ENV !== 'production' && (typeof icon === "undefined" || icon === null)) {
65 | console.warn("vue-icons - icon "+coll+"-"+name+" not found, is your webpack set up correctly?")
66 | }
67 | return icon
68 | }
69 | """
70 |
--------------------------------------------------------------------------------
/src/icon-stack.coffee:
--------------------------------------------------------------------------------
1 | # out: ../icon-stack.js
2 | i = require "./icon"
3 | iconStack =
4 | render: ->
5 | `with(this){//`
6 | return _h 'svg',
7 | style:(computedStyle)
8 | attrs:
9 | "version":"1.1"
10 | "role": if label then 'img' else 'presentation'
11 | "aria-label":label
12 | "width":outerWidth
13 | "height":outerHeight
14 | "viewBox":box
15 | ,[_h 'path',
16 | attrs:
17 | "d":icon.d
18 | "transform":flipped
19 | "fill":"currentColor"
20 | ]
21 | `}`
22 |
23 | mixins: i.mixins
24 | data: i.data
25 | mounted: i.mounted
26 | props: {}
27 | computed:
28 | isStack: -> true
29 | mergeStyle: ->
30 | return {
31 | left: "0"
32 | position: "absolute"
33 | }
34 | outerWidth: -> @$parent.outerWidth
35 | outerHeight: -> @$parent.outerHeight
36 |
37 | for prop in ["name","offsetX","offsetY","flipH","flipV","label","style","size","scale"]
38 | iconStack.props[prop] = i.props[prop]
39 | for c in ["processedName","icon","box","aspect","flipped","innerHeight","innerWidth","widthRatio","heightRatio"]
40 | iconStack.computed[c] = i.computed[c]
41 |
42 | module.exports = iconStack
43 |
--------------------------------------------------------------------------------
/src/icon.vue:
--------------------------------------------------------------------------------
1 | // out: ..
2 |
3 | span(v-bind:style="computedStyle")
4 | svg(version="1.1",
5 | :role="label ? 'img' : 'presentation'",
6 | :aria-label="label",
7 | :width="outerWidth",
8 | :height="outerHeight",
9 | :viewBox="box"
10 | )
11 | path(
12 | :d="icon.d",
13 | :transform="flipped",
14 | fill="currentColor")
15 | slot
16 |
17 |
18 |
130 |
--------------------------------------------------------------------------------
/src/process-fonts.coffee:
--------------------------------------------------------------------------------
1 | fs = require "fs"
2 | svgfont2js = require "svgfont2js"
3 | SVGO = require "svgo"
4 | svgo = new SVGO()
5 | Promise = require "bluebird"
6 | path = require "path"
7 | svgpath = require("svgpath")
8 |
9 | loadAliases = (less,re) ->
10 | m = {}
11 | match = undefined
12 | while null != (match = re.exec(less))
13 | alias = match[1]
14 | unicode_hex = match[2]
15 | m[unicode_hex] = [] unless m[unicode_hex]?
16 | m[unicode_hex].push(alias)
17 | return m
18 |
19 | sets =
20 | fa:
21 | re: /@fa-var-([a-z0-9-]+)\s*:\s*"\\([0-9a-f]+)";/g
22 | style: "font-awesome/less/variables.less"
23 | svg: "font-awesome/fonts/fontawesome-webfont.svg"
24 | glyphicon:
25 | re: /glyphicon-([^\s]*)[^\n]*content: "\\([^"]*)"/g
26 | style: "bootstrap/less/glyphicons.less"
27 | svg: "bootstrap/fonts/glyphicons-halflings-regular.svg"
28 | translateY: 240
29 | mdi:
30 | svg: "mdi/fonts/materialdesignicons-webfont.svg"
31 | octicon:
32 | folder: "octicons/lib/svg"
33 | re: /([A-Za-z0-9-]+).svg/
34 |
35 | material:
36 | svg: "material-design-icons/iconfont/MaterialIcons-Regular.svg"
37 | iconic:
38 | svg: "open-iconic/font/fonts/open-iconic.svg"
39 | style: "open-iconic/font/css/open-iconic.css"
40 | re: /\.oi\[data-glyph=([^\]]+)\]:before { content:'\\([^']+)'; }/g
41 | im:
42 | folder: "icomoon-free-npm/SVG"
43 | re: /[0-9]+-([A-Za-z0-9-]+).svg/
44 | ra:
45 | svg: "ratchet/fonts/ratchicons.svg"
46 |
47 | processSet = (setname,set) ->
48 | console.log "processing " + setname
49 | re = /d="([\w\s-.]*)"/
50 | optimizers = []
51 | if set.svg
52 | if set.re
53 | aliases = loadAliases(fs.readFileSync(require.resolve(set.style, "utf8")),set.re)
54 | glyphs = svgfont2js(fs.readFileSync(require.resolve(set.svg, "utf8")))
55 | for glyph in glyphs
56 | optimizers.push new Promise (resolve) ->
57 | d = new svgpath(glyph.path)
58 | if set.translateY
59 | d = d.translate(0, set.translateY)
60 | d = d.rel().toString()
61 | svgo.optimize "", (result) ->
62 | match = re.exec(result.data)
63 | if match?[1]
64 | glyph.path = match[1]
65 | resolve glyph
66 | else
67 | console.log "#{setname}: #{glyph.name} failed to match"
68 | resolve null
69 | else if set.folder
70 | processFile = (file,name) ->
71 | optimizers.push new Promise (resolve) ->
72 | fs.readFile folder+"/"+file,encoding:"utf8", (err,content) ->
73 | return resolve null if err
74 | svgo.optimize content, (result) ->
75 | d = re.exec(result.data)
76 | box = /viewBox="0 0 ([0-9]+) ([0-9]+)"/.exec(result.data)
77 | if d? and d.length > 1 and box? and box.length > 2
78 | resolve {
79 | name: name
80 | path: d[1]
81 | width: box[1]
82 | height: box[2]
83 | }
84 | else
85 | console.log "#{setname}: #{name} failed to match"
86 | resolve null
87 | folder = path.resolve("node_modules/"+set.folder)
88 | for file,i in fs.readdirSync(folder)
89 | if file
90 | name = set.re.exec(file)
91 | if name?[1]
92 | processFile(file,name[1])
93 |
94 |
95 | Promise.all(optimizers)
96 | .then (glyphs) ->
97 | data = {aliases:{},icons:{}}
98 | for glyph in glyphs
99 | if glyph?
100 | if set.svg and set.re
101 | tmp = glyph['unicode_hex']
102 | if tmp.length == 2
103 | tmp = "00"+tmp
104 | else if tmp.length == 3
105 | tmp = "0"+tmp
106 | names = aliases[tmp]
107 | else
108 | names = [glyph.name]
109 | if names?
110 | name = names.shift()
111 | icon =
112 | d: glyph.path
113 | w: glyph.width
114 | h: glyph.height
115 | if names.length > 0
116 | for alias in names
117 | data.aliases[alias] = name
118 | icon.aliases = names
119 | data.icons[name] = icon
120 | console.log setname + " " + glyphs.length + " glyphs " + Object.keys(data.icons).length + " icons " + Object.keys(data.aliases).length + " aliases"
121 | return data
122 | .then JSON.stringify
123 | .then (string) ->
124 | fs.writeFileSync(path.resolve(__dirname+"/../icons/#{setname}.json"),string)
125 | for setname, set of sets
126 | processSet(setname,set)
127 |
--------------------------------------------------------------------------------
/test/icon.coffee:
--------------------------------------------------------------------------------
1 | env = null
2 | describe "icon", ->
3 |
4 | describe "basic env", ->
5 |
6 | before ->
7 | env = loadComp(require("../dev/basic.vue"))
8 |
9 | after ->
10 | unloadComp(env)
11 |
12 | it "should font awesome", ->
13 | el = env.$refs.fa.$el.firstChild
14 | el.should.have.attr "viewBox", "0 0 1792 1792"
15 | el.firstChild.should.have.attr "d","M1699 186q0 35-43 78l-632 632v768h320q26 0 45 19t19 45-19 45-45 19H448q-26 0-45-19t-19-45 19-45 45-19h320V896L136 264q-43-43-43-78 0-23 18-36.5t38-17.5 43-4h1408q23 0 43 4t38 17.5 18 36.5z"
16 |
17 | it "should material design icons", ->
18 | el = env.$refs.mdi.$el.firstChild
19 | el.should.have.attr "viewBox", "0 0 512 512"
20 | el.firstChild.should.have.attr "d","M213.3 85.3c47.2 0 85.4 38.2 85.4 85.4S260.5 256 213.3 256 128 217.8 128 170.7s38.2-85.4 85.3-85.4m0 213.4c94.3 0 170.7 38.2 170.7 85.3v42.7H42.7V384c0-47.1 76.3-85.3 170.6-85.3M426.7 256V149.3h42.6V256h-42.6m0 85.3v-42.6h42.6v42.6h-42.6z"
21 |
22 | it "should google material icons", ->
23 | el = env.$refs.material.$el.firstChild
24 | el.should.have.attr "viewBox", "0 0 512 512"
25 | el.firstChild.should.have.attr "d","M484 405c9 6 9 21-2 30l-49 49c-9 9-21 9-30 0L209 290c-49 19-106 9-147-32-43-43-54-107-28-158l94 92 64-64-92-92c51-23 115-15 158 28 41 41 51 98 32 147z"
26 |
27 | it "should octicons", ->
28 | el = env.$refs.octicon.$el.firstChild
29 | el.should.have.attr "viewBox", "0 0 45 16"
30 | el.firstChild.should.have.attr "d","M18.53 12.03h-.02c.009 0 .015.01.024.011h.006l-.01-.01zm.004.011c-.093.001-.327.05-.574.05-.78 0-1.05-.36-1.05-.83V8.13h1.59c.09 0 .16-.08.16-.19v-1.7c0-.09-.08-.17-.16-.17h-1.59V3.96c0-.08-.05-.13-.14-.13h-2.16c-.09 0-.14.05-.14.13v2.17s-1.09.27-1.16.28c-.08.02-.13.09-.13.17v1.36c0 .11.08.19.17.19h1.11v3.28c0 2.44 1.7 2.69 2.86 2.69.53 0 1.17-.17 1.27-.22.06-.02.09-.09.09-.16v-1.5a.177.177 0 0 0-.146-.18zm23.696-2.2c0-1.81-.73-2.05-1.5-1.97-.6.04-1.08.34-1.08.34v3.52s.49.34 1.22.36c1.03.03 1.36-.34 1.36-2.25zm2.43-.16c0 3.43-1.11 4.41-3.05 4.41-1.64 0-2.52-.83-2.52-.83s-.04.46-.09.52c-.03.06-.08.08-.14.08h-1.48c-.1 0-.19-.08-.19-.17l.02-11.11c0-.09.08-.17.17-.17h2.13c.09 0 .17.08.17.17v3.77s.82-.53 2.02-.53l-.01-.02c1.2 0 2.97.45 2.97 3.88zm-8.72-3.61H33.84c-.11 0-.17.08-.17.19v5.44s-.55.39-1.3.39-.97-.34-.97-1.09V6.25c0-.09-.08-.17-.17-.17h-2.14c-.09 0-.17.08-.17.17v5.11c0 2.2 1.23 2.75 2.92 2.75 1.39 0 2.52-.77 2.52-.77s.05.39.08.45c.02.05.09.09.16.09h1.34c.11 0 .17-.08.17-.17l.02-7.47c0-.09-.08-.17-.19-.17zm-23.7-.01h-2.13c-.09 0-.17.09-.17.2v7.34c0 .2.13.27.3.27h1.92c.2 0 .25-.09.25-.27V6.23c0-.09-.08-.17-.17-.17zm-1.05-3.38c-.77 0-1.38.61-1.38 1.38 0 .77.61 1.38 1.38 1.38.75 0 1.36-.61 1.36-1.38 0-.77-.61-1.38-1.36-1.38zm16.49-.25h-2.11c-.09 0-.17.08-.17.17v4.09h-3.31V2.6c0-.09-.08-.17-.17-.17h-2.13c-.09 0-.17.08-.17.17v11.11c0 .09.09.17.17.17h2.13c.09 0 .17-.08.17-.17V8.96h3.31l-.02 4.75c0 .09.08.17.17.17h2.13c.09 0 .17-.08.17-.17V2.6c0-.09-.08-.17-.17-.17zM8.81 7.35v5.74c0 .04-.01.11-.06.13 0 0-1.25.89-3.31.89-2.49 0-5.44-.78-5.44-5.92S2.58 1.99 5.1 2c2.18 0 3.06.49 3.2.58.04.05.06.09.06.14L7.94 4.5c0 .09-.09.2-.2.17-.36-.11-.9-.33-2.17-.33-1.47 0-3.05.42-3.05 3.73s1.5 3.7 2.58 3.7c.92 0 1.25-.11 1.25-.11v-2.3H4.88c-.11 0-.19-.08-.19-.17V7.35c0-.09.08-.17.19-.17h3.74c.11 0 .19.08.19.17z"
31 |
32 | it "should iconic", ->
33 | el = env.$refs.iconic.$el.firstChild
34 | el.should.have.attr "viewBox", "0 0 900 800"
35 | el.firstChild.should.have.attr "d","M551 0c16 0 32 0 47 3l-97 97v200h200l97-97c3 15 3 31 3 47 0 138-112 250-250 250-32 0-62-8-90-19L173 772c-20 20-46 28-72 28s-52-8-72-28c-39-39-39-105 0-144l291-287c-11-28-19-59-19-91C301 112 413 0 551 0zM101 650c-28 0-50 22-50 50s22 50 50 50 50-22 50-50-22-50-50-50z"
36 |
37 | it "should glyphicon", ->
38 | el = env.$refs.glyphicon.$el.firstChild
39 | el.should.have.attr "viewBox", "0 0 1200 1200"
40 | el.firstChild.should.have.attr "d","M649 251q48-68 109.5-104T880 108.5t118.5 20 102.5 64 71 100.5 27 123q0 57-33.5 117.5t-94 124.5T945 785.5 795 938t-146 174q-62-85-145.5-174t-150-152.5T227 658t-93.5-124.5T100 416q0-64 28-123t73-100.5 104-64 119-20T544.5 147 649 251z"
41 |
42 | it "should icomoon", ->
43 | el = env.$refs.im.$el.firstChild
44 | el.should.have.attr "viewBox", "0 0 16 16"
45 | el.firstChild.should.have.attr "d","M4.055 8a1.851 1.851 0 1 1 3.703 0 1.851 1.851 0 0 1-3.703 0zM8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zM5.928 14.989C3.522 13.589 1.905 10.984 1.905 8s1.617-5.589 4.023-6.989C8.334 2.41 9.953 5.016 9.953 8s-1.618 5.589-4.025 6.989z"
46 |
47 | it "should flip horizontal", ->
48 | el = env.$refs.horizontal.$el.firstChild
49 | el.should.have.attr "viewBox", "0 -1792 2048 1792"
50 | el.firstChild.should.have.attr "transform","scale(1,-1)"
51 |
52 | it "should flip vertical", ->
53 | el = env.$refs.vertical.$el.firstChild
54 | el.should.have.attr "viewBox", "-1792 0 1792 1792"
55 | el.firstChild.should.have.attr "transform","scale(-1,1)"
56 |
57 | it "should flip both", ->
58 | el = env.$refs.flipboth.$el.firstChild
59 | el.should.have.attr "viewBox", "-512 -512 512 512"
60 | el.firstChild.should.have.attr "transform","scale(-1,-1)"
61 | it "should size", ->
62 | el = env.$refs.size.$el.firstChild
63 | el.should.have.attr "height", "32"
64 |
65 | it "should scale", ->
66 | el = env.$refs.scale.$el.firstChild
67 | el.should.have.attr "height", "32"
68 |
69 | it "should color", ->
70 | el = env.$refs.color.$el
71 | el.should.have.attr("style").match(/color: red/)
72 |
73 | it "should hcenter", (done) ->
74 | el = env.$refs.hcenter.$el
75 | env.$nextTick -> env.$nextTick ->
76 | box = el.getBoundingClientRect()
77 | box.height.should.equal 40
78 | box = el.firstChild.getBoundingClientRect()
79 | box.height.should.equal 40
80 | done()
81 |
82 |
83 | describe "font-compatible env", ->
84 |
85 | before ->
86 | env = loadComp(require("../dev/font-compatible.vue"))
87 |
88 | after ->
89 | unloadComp(env)
90 |
91 | it "should size", (done) ->
92 | el = env.$refs.size.$el.firstChild
93 | env.$nextTick ->
94 | env.$refs.size.innerHeight.should.equal 20
95 | done()
96 |
97 | it "should line-height", (done) ->
98 | el = env.$refs.lineHeight.$el.firstChild
99 | env.$nextTick ->
100 | el.should.have.attr "height", "40"
101 | done()
102 |
--------------------------------------------------------------------------------