Skip to content

Instantly share code, notes, and snippets.

@navad
Last active October 9, 2016 02:25
Show Gist options
  • Save navad/c6da12424ef9bc573700 to your computer and use it in GitHub Desktop.
Save navad/c6da12424ef9bc573700 to your computer and use it in GitHub Desktop.
Grunticon embedder for use in Angular directives/templates
/* globals grunticon: false */
(function() {
'use strict';
angular.module('ngGrunticon', [])
.provider('grunticonEmbedConfig', function() {
this.gruntIcons = undefined;
this.init = function(grunticonCss) {
var css = grunticon.getCSS(grunticonCss);
css = css ? css : window.document.querySelector('[data-grunticon-css]');
if (css) {
this.gruntIcons = {};
var icons = grunticon.getIcons(css);
Object.keys(icons).forEach(function(key) {
var selector = key.slice('grunticon:.'.length);
this.gruntIcons[selector] = icons[key];
}, this);
}
};
this.$get = function() {
return this;
};
})
.directive('grunticonEmbed', function($log, grunticonEmbedConfig) {
return {
restrict: 'A',
scope: {
grunticonEmbed: '@'
},
controller: function($scope, $element) {
$scope.$watch('grunticonEmbed', function(newClass, oldClass) {
if (oldClass) {
$element.removeClass(oldClass);
}
if (newClass) {
$element.addClass(newClass);
}
embedIcon($element);
});
}
};
function embedIcon(element) {
if (grunticonEmbedConfig.gruntIcons) {
var classListArray = element[0].classList.toString().split(' ');
var icons = arrayIntersection(classListArray, Object.keys(grunticonEmbedConfig.gruntIcons));
if (icons.length === 1) {
element[0].innerHTML = grunticonEmbedConfig.gruntIcons[icons[0]];
element[0].style.backgroundImage = 'none';
}
} else {
$log.error('Grunticon CSS not configured! please use ' +
'\'grunticonEmbedConfigProvider.init()\' to configure.');
}
}
});
// Utility
function arrayIntersection(array1, array2) {
return array1.filter(function(n) {
return array2.indexOf(n) !== -1;
});
}
})();
@navad
Copy link
Author

navad commented Oct 20, 2015

ngGrunticon

Since Grunticon loader does not support embedding SVG on dynamic content when using Angular, you can this directive instead of the default loader.

Usage:

  1. Add grunticon.loader.js to you index.html and make sure to use enhanceSVG: true in your Grunticon configuration.
    DON'T add the grunticon(...) call to your script - the directive will do it for you

  2. Add ngGrunticon module to you main angular app

  3. Configure grunticonEmbed in your app.config:

        app.config(function(grunticonEmbedConfigProvider) {
            grunticonEmbedConfigProvider.init('css/style.css');
        });

    -or- mark your icons css with data-grunticon-css attribute

  4. That's it! Use data-grunticon-embed as usual, according to Grunticon manual

Note:

  • Not tested with PNG fallback
  • Not tested with other browsers except Chrome 45

@navad
Copy link
Author

navad commented Oct 26, 2015

Gist updated to support dynamic class name + other improvements.

Dynamic class name:

Ideally, we would like the embedded to work with DOM element which has ng-class in them to select dynamically the name of the icon to show. However, we couldn't make our embedded to work after ng-class has finished injecting the classes to the DOM element. Therefore, we had to do some workaround:

Not working: <div ng-class="myIcon" data-grunticon-embed>
Working: <div data-grunticon-embed="{{ myIcon }}">

If anyone has a better idea we would love to hear

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment