public/components/icons/icons.js (33 lines of code) (raw):

/** * Icon directive that inserts SVG elements which reuse paths from a single * SVG sprite injected into the bottom of the document head. * * Usage: * <i wf-icon="example" /> * * Appends SVG: * <svg class="wf-icon--active wf-icon-type--example" viewBox="0 0 128 128"> * <use xlink:href="#icon-example"></use> * </svg> * * Icon Sprite file: * <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128"> * <defs> * <g id="example"> * <path d="..." /> * </g> * </defs> * </svg> */ import angular from 'angular'; // Aggregation icons import icons from './icons.svg'; // SVG Namespace var SVG_NS = 'http://www.w3.org/2000/svg'; var XLINK_NS = 'http://www.w3.org/1999/xlink'; // inject icons into <head> angular.element(document.head).append(icons); angular.module('wfIcons', []) .directive('wfIcon', wfIconDirective); function wfIconDirective() { return { restrict: 'A', scope: { wfIcon: '@', wfIconActive: '=' // boolean }, link: function($scope, $element) { // Create the icon element // Needs to be created this way with explicit Namespace as Angular // template creates HTML nodes rather than SVG. var iconElem = document.createElementNS(SVG_NS, 'svg'); iconElem.setAttribute('viewBox', '0 0 150 150'); var useElem = iconElem.appendChild(document.createElementNS(SVG_NS, 'use')); $element.append(iconElem); function updateIconClass() { iconElem.setAttribute('class', [ 'wf-icon--' + ($scope.wfIconActive !== false ? 'active' : 'inactive'), 'wf-icon-type--' + $scope.wfIcon ].join(' ')); } $scope.$watch('wfIconActive', updateIconClass); $scope.$watch('wfIcon', (newValue) => { useElem.setAttributeNS(XLINK_NS, 'href', '#icon-' + newValue); updateIconClass(); }); } }; }