File

src/icon/icon.directive.ts

Description

A directive for populating a svg element based on the provided carbon icon name.

Get started with importing the module:

Example :
import { IconModule } from 'carbon-components-angular';

See demo

Implements

AfterViewInit OnChanges

Metadata

Index

Properties
Methods
Inputs
Accessors

Constructor

constructor(elementRef: ElementRef, iconService: IconService)
Parameters :
Name Type Optional
elementRef ElementRef No
iconService IconService No

Inputs

ariaHidden
Type : string
Default value : ""
ariaLabel
Type : string
Default value : ""
ariaLabelledBy
Type : string
Default value : ""
cdsIcon
Type : string
Default value : ""
ibmIcon
Type : string
isFocusable
Type : boolean
Default value : false
size
Type : string
Default value : "16"
title
Type : string
Default value : ""

Methods

ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnChanges
ngOnChanges(undefined: SimpleChanges)
Parameters :
Name Type Optional
SimpleChanges No
Returns : void
renderIcon
renderIcon(iconName: string)
Parameters :
Name Type Optional
iconName string No
Returns : void

Properties

Static titleIdCounter
Type : number
Default value : 0

Accessors

ibmIcon
setibmIcon(iconName: string)
Parameters :
Name Type Optional
iconName string No
Returns : void
import {
	AfterViewInit,
	Directive,
	ElementRef,
	Input,
	OnChanges,
	SimpleChanges
} from "@angular/core";
import { IconService } from "./icon.service";
import { getAttributes } from "@carbon/icon-helpers";

/**
 * A directive for populating a svg element based on the provided carbon icon name.
 *
 * Get started with importing the module:
 *
 * ```typescript
 * import { IconModule } from 'carbon-components-angular';
 * ```
 *
 * [See demo](../../?path=/story/components-icon--basic)
 */
@Directive({
	selector: "[cdsIcon], [ibmIcon]"
})
export class IconDirective implements AfterViewInit, OnChanges {

	/**
	 * @deprecated since v5 - Use `cdsIcon` input property instead
	 */
	@Input() set ibmIcon(iconName: string) {
		this.cdsIcon = iconName;
	}

	static titleIdCounter = 0;

	@Input() cdsIcon = "";

	@Input() size = "16";

	@Input() title = "";

	@Input() ariaLabel = "";

	@Input() ariaLabelledBy = "";

	@Input() ariaHidden = "";

	@Input() isFocusable = false;

	constructor(
		protected elementRef: ElementRef,
		protected iconService: IconService
	) {}

	renderIcon(iconName: string) {
		const root = this.elementRef.nativeElement as HTMLElement;

		let icon;
		try {
			icon = this.iconService.get(iconName, this.size.toString());
		} catch (error) {
			console.warn(error);
			// bail out
			return;
		}

		const domParser = new DOMParser();
		const rawSVG = icon.svg;
		const svgElement = domParser.parseFromString(rawSVG, "image/svg+xml").documentElement;

		let node: ChildNode = root.tagName.toUpperCase() !== "SVG" ? svgElement : svgElement.firstChild;
		root.innerHTML = ""; // Clear root element
		while (node) {
			// importNode makes a clone of the node
			// this ensures we keep looping over the nodes in the parsed document
			root.appendChild(root.ownerDocument.importNode(node, true));
			// type the node because the angular compiler freaks out if it
			// ends up thinking it's a `Node` instead of a `ChildNode`
			node = node.nextSibling as ChildNode;
		}

		const svg = root.tagName.toUpperCase() !== "SVG" ? svgElement : root;
		const xmlns = "http://www.w3.org/2000/svg";
		svg.setAttribute("xmlns", xmlns);

		const attributes = getAttributes({
			width: icon.attrs.width,
			height: icon.attrs.height,
			viewBox: icon.attrs.viewBox,
			title: this.title,
			"aria-label": this.ariaLabel,
			"aria-labelledby": this.ariaLabelledBy,
			"aria-hidden": this.ariaHidden,
			focusable: this.isFocusable.toString(),
			fill: icon.attrs.fill
		});

		const attrKeys = Object.keys(attributes);
		for (let i = 0; i < attrKeys.length; i++) {
			const key = attrKeys[i];
			const value = attributes[key];

			if (key === "title") {
				continue;
			}

			if (value) {
				svg.setAttribute(key, value);
			}
		}

		if (attributes["title"]) {
			const title = document.createElementNS(xmlns, "title");
			title.textContent = attributes.title;
			IconDirective.titleIdCounter++;
			title.setAttribute("id", `${icon.name}-title-${IconDirective.titleIdCounter}`);
			// title must be first for screen readers
			svg.insertBefore(title, svg.firstElementChild);
			svg.setAttribute("aria-labelledby", `${icon.name}-title-${IconDirective.titleIdCounter}`);
		}
	}

	ngAfterViewInit() {
		this.renderIcon(this.cdsIcon);
	}

	ngOnChanges({ cdsIcon }: SimpleChanges) {
		// We want to ignore first change to let the icon register
		// and add only after view has been initialized
		if (cdsIcon && !cdsIcon.isFirstChange()) {
			this.renderIcon(this.cdsIcon);
		}
	}
}

results matching ""

    No results matching ""