Created
February 5, 2018 23:37
-
-
Save jolyndenning/7d391770baa2b738bdda179433154937 to your computer and use it in GitHub Desktop.
Angular custom elements support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* NOTE: that this code was written for https://github.com/CanopyTax and some parts might not be suitable for the generic use case. | |
It assumes that string data can be passed as both a property or an html attribute, and it prefers properties over attributes for everything. | |
USAGE: | |
- <x-foo attr1="'string'" /> | |
- <button is="my-button" /> | |
- <x-foo attr2="objOnScope" /> | |
*/ | |
import angular from 'angular'; | |
import {forEach, kebabCase, includes} from 'lodash'; | |
angular.module('app').directive('cpCustomElement', ['$parse', | |
function customElement($parse) { | |
return { | |
restrict: "A", | |
compile(preElem, attrs) { | |
forEach(attrs, (value, key) => { | |
if (shouldProcess(key)) { | |
preElem[0].removeAttribute(kebabCase(key)); | |
} | |
}) | |
return { | |
post(scope, elem) { | |
forEach(attrs, (value, key) => { | |
if (!shouldProcess(key)) return; | |
if (key.startsWith('on')) { | |
elem[0].addEventListener(key.slice(2).toLowerCase(), (e) => { | |
scope.$evalAsync(() => { | |
$parse(attrs[key])(scope, {e}); | |
}); | |
}); | |
} else { | |
const value = $parse(attrs[key])(scope); | |
setValue(elem[0], key, value); | |
scope.$watch(() => $parse(attrs[key])(scope), (newVal) => { | |
setValue(elem[0], key, newVal); | |
}) | |
} | |
}) | |
} | |
} | |
}, | |
} | |
} | |
]) | |
function shouldProcess(key) { | |
if (key.startsWith('$') || key.startsWith('ng') || key.startsWith('uib-') || key.startsWith('ui-')) | |
return false; | |
if (includes(['cpCustomElement', 'is', 'class', 'ignore-double-click', 'download'], key)) | |
return false; | |
return true; | |
} | |
function setValue(element, propertyName, value) { | |
if (typeof value === 'string') { | |
element.setAttribute(kebabCase(propertyName), value); | |
} else { | |
delete element[propertyName]; | |
element[propertyName] = value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment