-
Notifications
You must be signed in to change notification settings - Fork 161
Icon Service Specification
Team Name: Design Team
Developer Name: Simeon Simeonoff
- Damyan Petev | Date:
- Radoslav Karaivanov | Date:
Version | Users | Date | Notes |
---|---|---|---|
1 | Simeon Simeonoff | 2024-04-02 | Initial Draft |
2 | Simeon Simeonoff | 2024-04-08 | Updated API |
The IgxIconService
associates a specific resource, like an icon font or SVG, with a name and family that can later be used to reference the given resource.
Allow users to easily add and overwrite icons in their application.
One of the properties of the icon service should be to provide a way to give a font family some name within the context of the service. In most cases third-party icon fonts require users to apply a specific CSS class to the element used as a placeholder for the icon. Generaly, there are two ways to consume icons from a custom font. The first maps unicode glyph code points from the icon font to CSS classes. This naming mechanism allows icons to be used in HTML in the following way:
<i class="fas fa-home"></i>
Here, the class fas
refers to the general font family being used, in this case font-awesome solid
and fa-car
refers to the class that encapsulates the code point in the font family that is used as CSS content.
The second approach is to pass in the ligature
(if available) of the glyph we want to use as text content in the HTML element. The ligature (the icon name) will then resolve to the glyph code point in the font family.
<i class="material-icons">home</i>
This will resolve the home
glyph in the material icon font to the code point 0xe88a
.
-
I want to be able to include third-party font families so that they can be consumed in a standardized way via the
igx-icon
component./** * The icon service associates a given family name (provided by the user) * with a specific CSS class (as documented in the providing icon font) * and corresponding icon name (documented in the icon font). */ service.setFamily('material', { className: 'material-icons', type: 'liga' }); service.setFamily('fa-solid', { className: 'fas', type: 'font', prefix: 'fa' });
Later in markup:
<igx-icon family="material" name="home"></igx-icon> <igx-icon family="fa-solid" name="car"></igx-icon>
As users of the icon service, we have to know in advance what type of icon family we are dealing with and inform the icon service when setting icon families. When an icon font is ligature based, we set the type to
liga
in the family meta of thesetFamily
method. If the font family uses CSS classes that map to code points, we set the type tofont
. -
I want to be able to associate SVG images with families and give them names so that they can be included via the
igx-icon
component in the same way as font-based icons. The SVGs should be resolved via either strings or via absolute URI to the SVG asset.// Add a new 'material' icon called 'my-icon' from an SVG file iconService.addSvgIcon('my-icon', 'my-icon.svg', 'material'); // Add a new 'fa-solid' icon called 'my-icon' from string iconService.addSvgIconFromText('my-icon', '<svg>...</svg>', 'fa-solid');
Later in markup:
<igx-icon family="material" name="my-icon"></igx-icon> <igx-icon family="fa-solid" name="my-icon"></igx-icon>
-
I want to be able to create a pseudo family map that combines icons added via either setting a family of font icons or adding SVGs under a common umbrella so that it's easier to reference them.
// The `setIconRef` sets an icon reference in the icon map, // assuming material and fa-solid have been added as families, iconService.setIconRef('home', 'my-family', { family: 'material', name: 'home' }); iconService.setIconRef('home-alt', 'my-family', { family: 'fa-solid', name: 'home' }); iconService.setIconRef('car', 'my-family', { family: 'fa-solid', name: 'car' });
Later in markup:
<igx-icon family="my-family" name="home"></igx-icon> <igx-icon family="my-family" name="home-alt"></igx-icon> <igx-icon family="my-family" name="car"></igx-icon>
-
I want to be able to get an icon for a given
family
and iconname
so that I know what the original icontype
,name
,family
andclassName
are.const { family, className, name, type } = iconService.getIcon('my-family', 'car'); console.log(family); // -> 'fa-solid' console.log(className); // -> 'fas' console.log(name); // -> 'fa-car' console.log(type); // -> 'font'
-
I want to be able to overwrite the icons encapsulated by a given component with my own icon mappings.
What should we do here? Do we want to support overwriting icons per component instance? If not, doing the following should be enough:
Some component in Ignite UI for Angular:
constructor(private iconService: IgxIconService) {} ngOnInit() { // Add the icon to the cache this.iconService.addSvgIconFromText('contains', '<svg>...</svg>', 'imx-icons'); // This only adds the icon in the ref map by calling `setIconRef` if it does not exist this.iconService.addIconRef('contains', 'default', { family: 'imx-icons', name: 'contains' }); }
Component template:
<igx-icon family="default" name="contains"></igx-icon>
User-land component using the Ignite UI for Angular component and overwriting the
contains
icon in thedefault
family:constructor(private iconService: IgxIconService) {} ngOnInit() { service.setFamily('line-awesome', { className: 'las', type: 'font' }); this.iconService.setIconRef('contains', 'default', { family: 'line-awesome', name: 'box' }); }
-
I want to be able to provide a prefix when setting a font family, so that I can just call the icon by name without the given prefix. Providing the full name including the icon prefix should still work.
setFamily(name: 'font-awesome', { className: 'fas', prefix: 'fa', type: 'font' }): IgxIconService;
<!--You don't need to include the prefix in the icon name--> <igx-icon family="font-awesome" name="car"></igx-icon> <!--Providing the full name, including prefix, still works--> <igx-icon family="font-awesome" name="fa-car"></igx-icon>
-
Icons can be one of three types: SVG, font and ligature.
type IconType = "svg" | "font" | "liga";
-
Icons are represented in the following way:
interface IconMeta { name: string; family: string; type?: IconType; }
-
Icon Families are registered with the following metadata:
interface FamilyMeta { className: string; type: IconType; prefix?: string; }
-
Mapped icons are represented using the following type:
type IconReference = IconMeta & IconFamilyMeta;
Families are stored in a Map with the following signature:
Map<string, IconFamilyMeta>
Example:
iconService.setFamily('fa-solid', { class: 'fas', type: 'font', prefix: 'fa' });
// The map holding the families now looks like this:
[{
key: 'fa-solid',
value: {
className: 'fas',
type: 'font',
prefix: 'fa'
}
}]
The key is the family name, the value is the metadata.
Icon mappings are stored in a Map with the following signature:
Map<string, Map<string, IconMeta>>
Example:
iconService.setIconRef('car', 'default', { family: 'fa-solid', name: 'car', type: 'font' });
// The mapped icons map now looks like this:
[{
key: 'default',
value: [{
key: 'car',
value: {
family: "fa-solid",
name: "car",
type: "font",
prefix: "fa"
}
}]
}]
The key is the name of the pseudo family collection, the value is the map of icon names to icons in the actual icon families.
-
Register a new family:
setFamily(name: string, meta: IconFamilyMeta): IgxIconService;
-
Add an Icon reference ONLY if NOT already present the icon map:
addIconRef(name: string, family: string, icon: IconMeta): void;
-
Set an Icon reference in the icon map:
setIconRef(name: string, family: string, icon: IconMeta): void;
-
Get an Icon reference from the icon map:
getIconRef(family: string, name: string): IconReference;
-
Add an SVG icon from URI:
addSvgIcon(name: string, url: string, family: string, stripMeta = false): void;
-
Add an SVG icon from string:
addSvgIconFromText(name: string, iconText: string, family: string, stripMeta = false): void;
- The end user is responsible for linking and settings font families in their applications.
- Adding multiple icons and/or families with the same name is supported, but the last declaration will overwrite any previous icon/family. It is highly recommended to use unique names for icons and families.
- Providing a combination of non-existing (not previously set) icons and families will silently fail and nothing will be displayed by the
igx-icon
component.