diff --git a/src/components/icon/demoFontIcons/index.html b/src/components/icon/demoFontIconsWithClassnames/index.html
similarity index 100%
rename from src/components/icon/demoFontIcons/index.html
rename to src/components/icon/demoFontIconsWithClassnames/index.html
diff --git a/src/components/icon/demoFontIcons/script.js b/src/components/icon/demoFontIconsWithClassnames/script.js
similarity index 94%
rename from src/components/icon/demoFontIcons/script.js
rename to src/components/icon/demoFontIconsWithClassnames/script.js
index 2ab14e9498c..f48f3e6160a 100644
--- a/src/components/icon/demoFontIcons/script.js
+++ b/src/components/icon/demoFontIconsWithClassnames/script.js
@@ -1,6 +1,6 @@
angular
- .module('appDemoFontIcons', ['ngMaterial'])
+ .module('appDemoFontIconsWithClassnames', ['ngMaterial'])
.controller('DemoCtrl', function( $scope ) {
// Create list of font-icon names with color overrides
var iconData = [
diff --git a/src/components/icon/demoFontIcons/style.css b/src/components/icon/demoFontIconsWithClassnames/style.css
similarity index 92%
rename from src/components/icon/demoFontIcons/style.css
rename to src/components/icon/demoFontIconsWithClassnames/style.css
index 7c9cca858d5..68a0ce47756 100644
--- a/src/components/icon/demoFontIcons/style.css
+++ b/src/components/icon/demoFontIconsWithClassnames/style.css
@@ -1,11 +1,11 @@
-.appDemoFontIcons {
+.appDemoFontIconsWithClassnames {
padding:25px;
width: 100%;
}
-.appDemoFontIcons,
-.appDemoFontIcons *:before,
-.appDemoFontIcons *:after {
+.appDemoFontIconsWithClassnames,
+.appDemoFontIconsWithClassnames *:before,
+.appDemoFontIconsWithClassnames *:after {
box-sizing: border-box;
}
@@ -18,7 +18,7 @@
line-height:1;
font-weight:normal;
font-style:normal;
- speak:none;
+
text-decoration:inherit;
text-transform:none;
text-rendering:optimizeLegibility;
diff --git a/src/components/icon/demoFontIconsWithLigatures/index.html b/src/components/icon/demoFontIconsWithLigatures/index.html
new file mode 100644
index 00000000000..cfb6b2ac239
--- /dev/null
+++ b/src/components/icon/demoFontIconsWithLigatures/index.html
@@ -0,0 +1,31 @@
+
+
+
+ Display 4 Material Design font-icons using ligatures [instead of CSS names]; each with different sizes and colors
+
+
+
+
+
+
+
+
+ {{ font.name }}
+
+
+
+
+
+
+ Cool Tip:
+ Copy an icon and then paste in a text editor to see its textual name!
+
+
+
+
+
diff --git a/src/components/icon/demoFontIconsWithLigatures/script.js b/src/components/icon/demoFontIconsWithLigatures/script.js
new file mode 100644
index 00000000000..f63ac463593
--- /dev/null
+++ b/src/components/icon/demoFontIconsWithLigatures/script.js
@@ -0,0 +1,23 @@
+
+angular
+ .module('appDemoFontIconsWithLigatures', ['ngMaterial'])
+ .controller('DemoCtrl', function( $scope ) {
+ // Specify a list of font-icons with ligatures and color overrides
+ var iconData = [
+ {name: 'accessibility' , color: "#777" },
+ {name: 'question_answer', color: "rgb(89, 226, 168)" },
+ {name: 'backup' , color: "#A00" },
+ {name: 'email' , color: "#00A" }
+ ];
+
+ $scope.fonts = [].concat(iconData);
+
+ // Create a set of sizes...
+ $scope.sizes = [
+ {size:"md-18",padding:0},
+ {size:"md-24",padding:2},
+ {size:"md-36",padding:6},
+ {size:"md-48",padding:10}
+ ];
+
+ });
diff --git a/src/components/icon/demoFontIconsWithLigatures/style.css b/src/components/icon/demoFontIconsWithLigatures/style.css
new file mode 100644
index 00000000000..0a1338dc79e
--- /dev/null
+++ b/src/components/icon/demoFontIconsWithLigatures/style.css
@@ -0,0 +1,73 @@
+
+.appDemoFontIconsWithLigatures {
+ padding:25px;
+ width: 100%;
+}
+.appDemoFontIconsWithLigatures,
+.appDemoFontIconsWithLigatures *:before,
+.appDemoFontIconsWithLigatures *:after {
+ box-sizing: border-box;
+}
+
+header {
+ overflow: hidden;
+}
+
+header h1 {
+ color: #888;
+ font-size: 36px;
+ font-weight: 300;
+}
+
+.container {
+ margin: 0 auto;
+ max-width: 1200px;
+ min-width: 960px;
+ padding: 40px 40px;
+ font: 14px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+.glyph {
+ border-bottom: 1px dotted #ccc;
+ padding: 10px 0 20px;
+ margin-bottom: 20px;
+}
+
+.preview-scale,
+.preview-glyphs {
+ display: flex;
+ flex-direction: row;
+}
+
+.preview-scale {
+ color: #888;
+ font-size: 12px;
+ margin-top: 24px;
+}
+
+.step {
+ flex-grow: 1;
+ line-height: 0.5;
+}
+
+.usage { margin-top: 10px; }
+.usage input {
+ font-family: monospace;
+ text-align: center;
+}
+.usage .point { width: 150px; }
+.usage .class { width: 250px; }
+
+/* Rules for sizing the icon.*/
+.material-icons.md-18 { font-size: 18px; }
+.material-icons.md-24 { font-size: 24px; }
+.material-icons.md-36 { font-size: 36px; }
+.material-icons.md-48 { font-size: 48px; }
+
+/* Rules for using icons as black on a light background.*/
+.material-icons.md-dark { color: rgba(0, 0, 0, 0.54); }
+.material-icons.md-dark.md-inactive { color: rgba(0, 0, 0, 0.26); }
+
+/* Rules for using icons as white on a dark background.*/
+.material-icons.md-light { color: rgba(255, 255, 255, 1); }
+.material-icons.md-light.md-inactive { color: rgba(255, 255, 255, 0.3); }
diff --git a/src/components/icon/iconDirective.js b/src/components/icon/iconDirective.js
index 3d1c8cffed4..540fc386367 100644
--- a/src/components/icon/iconDirective.js
+++ b/src/components/icon/iconDirective.js
@@ -17,44 +17,146 @@ angular.module('material.components.icon', [
* @restrict E
*
* @description
- * The `md-icon` directive is an markup element useful for showing an icon based on a font-face
- * or a SVG. Both external SVGs (via URLs) or cached SVG from icon sets can be
- * easily loaded and used.
+ * The `` directive is an markup element useful for showing an icon based on a font-icon
+ * or a SVG. Icons are view-only elements that should not be used directly as buttons; instead nest a ``
+ * inside a `md-button` to add hover and click features.
*
+ * When using SVGs, both external SVGs (via URLs) or sets of SVGs [from icon sets] can be
+ * easily loaded and used.When use font-icons, developers must following three (3) simple steps:
+ *
+ *
+ *
Load the font library. e.g.
+ * <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
+ * rel="stylesheet">
+ *
+ *
Use either (a) font-icon class names or (b) font ligatures to render the font glyph by using its textual name
+ *
Use <md-icon md-font-icon="classname" /> or
+ * use <md-icon md-font-library="library_style_name"> textual_name </md-icon> or
+ * use <md-icon md-font-library="library_style_name"> numerical_character_reference </md-icon>
+ *
+ *
+ *
+ * Full details for these steps can be found:
+ *
+ *
+ * Using the Material Design Icon-Selector, developers can easily and quickly search for a Material Design font-icon and
+ * determine its textual name and character reference code. Click on any icon to see the slide-up information
+ * panel with details regarding a SVG download or information on the font-icon usage.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Click on the image above to link to the
+ * Material Design Icon-Selector.
+ *
+ *
+ * @param {string} md-font-icon String name of CSS icon associated with the font-face will be used
+ * to render the icon. Requires the fonts and the named CSS styles to be preloaded.
+ * @param {string} md-font-library String name of CSS icon associated with the font-face will be used
+ * to render the icon. Requires the fonts and the named CSS styles to be preloaded.
* @param {string} md-svg-src String URL [or expression ] used to load, cache, and display an external SVG.
* @param {string} md-svg-icon String name used for lookup of the icon from the internal cache; interpolated strings or
* expressions may also be used. Specific set names can be used with the syntax `:`.
* To use icon sets, developers are required to pre-register the sets using the `$mdIconProvider` service.
- * @param {string} md-font-icon String name of CSS icon associated with the font-face will be used
- * to render the icon. Requires the fonts and the named CSS styles to be preloaded.
* @param {string=} alt Labels icon for accessibility. If an empty string is provided, icon
* will be hidden from accessibility layer with `aria-hidden="true"`. If there's no alt on the icon
* nor a label on the parent element, a warning will be logged to the console.
*
* @usage
+ * When using SVGs:
*
- *
- *
+ *
+ *
+ *
+ *
+ *
*
*
+ *
*
+ *
+ * Use the $mdIconProvider to configure your application with
+ * svg iconsets.
+ *
+ *
+ * angular.module('appSvgIconSets', ['ngMaterial'])
+ * .controller('DemoCtrl', function($scope) {})
+ * .config(function($mdIconProvider) {
+ * $mdIconProvider
+ * .iconSet('social', 'img/icons/sets/social-icons.svg', 24)
+ * .defaultIconSet('img/icons/sets/core-icons.svg', 24);
+ * });
+ *
+ *
+ *
+ * When using Font Icons with classnames:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * When using Font Icons with ligatures:
+ *
+ *
+ * face
+ * #xE87C;
+ * face
+ *
+ *
+ *
+ *
*/
-function mdIconDirective($mdIcon, $mdTheming, $mdAria ) {
+function mdIconDirective($mdIcon, $mdTheming, $mdAria, $interpolate ) {
+
return {
scope: {
+ fontLib: '@mdFontLibrary',
fontIcon: '@mdFontIcon',
svgIcon: '@mdSvgIcon',
svgSrc: '@mdSvgSrc'
},
restrict: 'E',
+ transclude:true,
template: getTemplate,
link: postLink
};
function getTemplate(element, attr) {
- return attr.mdFontIcon ? '' : '';
+ var hasAttrValue = function(key) { return attr[key] && attr[key].length };
+ var attrValue = function(key) { return hasAttrValue(key) ? attr[key] : '' };
+
+ // If using font-icons, transclude the ligature or NRCs
+ var tmpl = hasAttrValue('mdFontIcon') ? '' :
+ hasAttrValue('mdFontLibrary') ? '' : '';
+
+ // Transpose the mdFontLibrary name to the list of classnames
+ // For example, Material Icons expects classnames like `.material-icons.md-48` instead of `.material-icons .md-48`
+
+ var names = (attrValue('mdFontLibrary') + ' ' + attrValue('class')).trim();
+ element.attr('class',names);
+
+ return $interpolate( tmpl )({ classNames: names });
}
+
/**
* Directive postLink
* Supports embedded SVGs, font-icons, & external SVGs
@@ -62,15 +164,20 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria ) {
function postLink(scope, element, attr) {
$mdTheming(element);
+ // If using a font-icon, then the textual name of the icon itself
+ // provides the aria-label.
+
var ariaLabel = attr.alt || scope.fontIcon || scope.svgIcon;
var attrName = attr.$normalize(attr.$attr.mdSvgIcon || attr.$attr.mdSvgSrc || '');
- if (attr.alt != '' && !parentsHaveText()) {
- $mdAria.expect(element, 'aria-label', ariaLabel);
- $mdAria.expect(element, 'role', 'img');
- } else {
- // Hide from the accessibility layer.
- $mdAria.expect(element, 'aria-hidden', 'true');
+ if ( !attr.mdFontLibrary ) {
+ if (attr.alt != '' && !parentsHaveText() ) {
+ $mdAria.expect(element, 'aria-label', ariaLabel);
+ $mdAria.expect(element, 'role', 'img');
+ } else {
+ // Hide from the accessibility layer.
+ $mdAria.expect(element, 'aria-hidden', 'true');
+ }
}
if (attrName) {
diff --git a/src/components/icon/iconDirective.spec.js b/src/components/icon/iconDirective.spec.js
index 36350f507fb..1f20f669c08 100644
--- a/src/components/icon/iconDirective.spec.js
+++ b/src/components/icon/iconDirective.spec.js
@@ -2,37 +2,28 @@ describe('mdIcon directive', function() {
var el;
var $scope;
var $compile;
- var $q;
beforeEach(module('material.core'));
beforeEach(module('material.components.icon'));
-
- var mockIconSvc = function(id) {
- var deferred = $q.defer();
-
- function getIcon(id) {
- switch(id) {
- case 'android': return '';
- case 'cake': return '';
- case 'android.svg': return '';
- case 'cake.svg': return '';
- }
- }
-
- deferred.resolve(getIcon(id));
- return deferred.promise;
- }
-
- function make(html) {
- var el;
- el = $compile(html)($scope);
- $scope.$digest();
- return el;
- }
-
beforeEach(function() {
+ var $q;
+
module(function($provide) {
- $provide.value('$mdIcon', mockIconSvc);
+ $provide.value('$mdIcon', function $mdIconMock(id) {
+
+ function getIcon(id) {
+ switch(id) {
+ case 'android' : return '';
+ case 'cake' : return '';
+ case 'android.svg': return '';
+ case 'cake.svg' : return '';
+ }
+ }
+
+ return $q(function(resolve){
+ resolve(getIcon(id));
+ });
+ });
});
inject(function($rootScope, _$compile_, _$q_){
@@ -40,18 +31,54 @@ describe('mdIcon directive', function() {
$compile = _$compile_;
$q = _$q_;
});
+
});
- describe('using md-font-icon=""', function() {
+ describe('using font-icons with classnames: md-font-icon=""', function() {
it('should render correct HTML with md-font-icon value as class', function() {
el = make( '');
- expect(el.html()).toEqual('');
+ expect(el.html()).toEqual('');
+ });
+
+ it('should transclude class specifiers', function() {
+ el = make( '');
+ expect(el.html()).toEqual('');
+ });
+
+ it('should not render any inner content if the md-font-icon value is empty', function() {
+ el = make( '' );
+ expect(el.html()).toEqual('');
});
});
+ describe('using font-icons with ligatures: md-font-library=""', function() {
+
+ it('should render correct HTML with ligature and md-font-library value as class', function() {
+ el = make( 'face');
+
+ expect(el.html()).toEqual('face');
+ expect(el.attr('class').indexOf('material-icons md-48')).toBeGreaterThan(-1);
+ });
+
+ it('should render correct HTML without aria-label', function() {
+ el = make( 'face');
+ expect(el.html().indexOf('aria-label')).toEqual(-1);
+ });
+
+ it('should render correct HTML without aria-hidden', function() {
+ el = make( 'face');
+ expect(el.html().indexOf('aria-hidden')).toEqual(-1);
+ });
+
+ it('should render correct HTML without role attribute', function() {
+ el = make( 'face');
+ expect(el.html().indexOf('role')).toEqual(-1);
+ });
+ });
+
describe('using md-svg-icon=""', function() {
it('should update mdSvgIcon when attribute value changes', function() {
@@ -122,4 +149,17 @@ describe('mdIcon directive', function() {
});
+
+ // ****************************************************
+ // Internal utility methods
+ // ****************************************************
+
+ function make(html) {
+ var el;
+ el = $compile(html)($scope);
+ $scope.$digest();
+ return el;
+ }
+
+
});
diff --git a/src/components/icon/iconService.js b/src/components/icon/iconService.js
index f47b4167c9c..4cae6b7fc17 100644
--- a/src/components/icon/iconService.js
+++ b/src/components/icon/iconService.js
@@ -17,6 +17,7 @@
* the `$mdIcon` service searches its registry for the associated source URL;
* that URL is used to on-demand load and parse the SVG dynamically.
*
+ * @usage
*
* app.config(function($mdIconProvider) {
*
@@ -95,7 +96,7 @@
* @description
* Register a source URL for a 'named' set of icons; group of SVG definitions where each definition
* has an icon id. Individual icons can be subsequently retrieved from this cached set using
- * `$mdIcon( : )`
+ * `$mdIcon(:)`
*
* @param {string} id Icon name/id used to register the iconset
* @param {string} url specifies the external location for the data file. Used internally by `$http` to load the
@@ -125,7 +126,7 @@
* @description
* Register a source URL for the default 'named' set of icons. Unless explicitly registered,
* subsequent lookups of icons will failover to search this 'default' icon set.
- * Icon can be retrieved from this cached, default set using `$mdIcon( )`
+ * Icon can be retrieved from this cached, default set using `$mdIcon()`
*
* @param {string} url specifies the external location for the data file. Used internally by `$http` to load the
* data or as part of the lookup in `$templateCache` if pre-loading was configured.
@@ -298,7 +299,7 @@
* };
*
*
- * NOTE: The `md-icon` directive internally uses the `$mdIcon` service to query, loaded, and instantiate
+ * NOTE: The ` ` directive internally uses the `$mdIcon` service to query, loaded, and instantiate
* SVG DOM elements.
*/
function MdIconService(config, $http, $q, $log, $templateCache) {
diff --git a/src/components/tooltip/tooltip.js b/src/components/tooltip/tooltip.js
index 051daebc3d6..28415ae8d9a 100644
--- a/src/components/tooltip/tooltip.js
+++ b/src/components/tooltip/tooltip.js
@@ -135,7 +135,7 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe
};
var leaveHandler = function () {
var autohide = scope.hasOwnProperty('autohide') ? scope.autohide : attr.hasOwnProperty('mdAutohide');
- if ($document[0].activeElement !== parent[0] || autohide || mouseActive) {
+ if (autohide || mouseActive || ($document[0].activeElement !== parent[0]) ) {
setVisible(false);
}
mouseActive = false;