@i316/angular 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -2
- package/index.d.ts +55 -0
- package/index.js +139 -0
- package/package.json +36 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rahil316
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @i316/angular
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Angular directive behind every i316 Angular icon package. You normally don't install it directly: each collection package depends on it and re-exports it.
|
|
4
|
+
|
|
5
|
+
- Solar: `@i316/solar-angular` (`<svg solarIcon …>`)
|
|
6
|
+
- Phosphor: `@i316/phosphor-angular` (`<svg phosphorIcon …>`)
|
|
7
|
+
- Heroicons: `@i316/heroicons-angular` (`<svg heroIcon …>`)
|
|
8
|
+
- Lucide: `@i316/lucide-angular` (`<svg lucideIcon …>`)
|
|
9
|
+
|
|
10
|
+
The directive answers to any of these attributes, so icons from several collections can share one template: `svg[i316]`, `svg[solarIcon]`, `svg[phosphorIcon]`, `svg[heroIcon]`, `svg[lucideIcon]`.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { i316, providei316 } from '@i316/angular';
|
|
14
|
+
|
|
15
|
+
bootstrapApplication(App, { providers: [providei316({ size: 20 })] });
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Peer dependency: `@angular/core >= 17`. It's compiled in Angular's partial (linker) format, so it works in apps on Angular 17 and later.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
MIT, © 2026 rahil316. This package contains no icon artwork; each collection package carries its own icon license.
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { InjectionToken, OnChanges, Provider } from "@angular/core";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export type i316Node = [tag: string, attrs: Record<string, string>, children?: i316Node[]];
|
|
4
|
+
export interface i316Data {
|
|
5
|
+
displayName: string;
|
|
6
|
+
className: string;
|
|
7
|
+
stroke: boolean;
|
|
8
|
+
duotone: boolean;
|
|
9
|
+
attrs: Record<string, string>;
|
|
10
|
+
nodes: i316Node[];
|
|
11
|
+
}
|
|
12
|
+
export interface i316Defaults {
|
|
13
|
+
size?: number | string;
|
|
14
|
+
color?: string;
|
|
15
|
+
strokeWidth?: number | string;
|
|
16
|
+
secondaryColor?: string;
|
|
17
|
+
secondaryOpacity?: number | string;
|
|
18
|
+
/** Added to every icon's class list. */
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const i316_DEFAULTS: InjectionToken<i316Defaults>;
|
|
22
|
+
/**
|
|
23
|
+
* Default inputs for every icon in scope. Use in `bootstrapApplication`/route
|
|
24
|
+
* providers for the whole app, or in a component's `providers` for a subtree;
|
|
25
|
+
* nested providers merge over their parent's values.
|
|
26
|
+
*/
|
|
27
|
+
export declare function providei316(defaults: i316Defaults): Provider;
|
|
28
|
+
export declare class i316 implements OnChanges {
|
|
29
|
+
/** Icon data, e.g. `BellLinear` from a collection package. */
|
|
30
|
+
icon: i316Data;
|
|
31
|
+
/** Width and height. Default 24. */
|
|
32
|
+
size?: number | string;
|
|
33
|
+
/** Replaces the icon's theme color. Default `currentColor`. */
|
|
34
|
+
color?: string;
|
|
35
|
+
/** Overrides the stroke width on stroke-based styles; ignored on fill-based styles. */
|
|
36
|
+
strokeWidth?: number | string;
|
|
37
|
+
/** Color of the translucent layer on duotone styles; ignored elsewhere. */
|
|
38
|
+
secondaryColor?: string;
|
|
39
|
+
/** Opacity of the translucent layer on duotone styles; ignored elsewhere. */
|
|
40
|
+
secondaryOpacity?: number | string;
|
|
41
|
+
/** Accessible name: renders a `<title>` and sets `role="img"`; otherwise the icon is `aria-hidden`. */
|
|
42
|
+
title?: string;
|
|
43
|
+
private readonly host;
|
|
44
|
+
private readonly renderer;
|
|
45
|
+
private readonly defaults;
|
|
46
|
+
private renderedNodes;
|
|
47
|
+
private renderedAttrs;
|
|
48
|
+
private renderedClasses;
|
|
49
|
+
ngOnChanges(): void;
|
|
50
|
+
private render;
|
|
51
|
+
private append;
|
|
52
|
+
private createNode;
|
|
53
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<i316, never>;
|
|
54
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<i316, "svg[i316], svg[solarIcon], svg[phosphorIcon], svg[heroIcon], svg[lucideIcon]", never, { "icon": { "alias": "icon"; "required": true; }; "size": { "alias": "size"; "required": false; }; "color": { "alias": "color"; "required": false; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; }; "secondaryColor": { "alias": "secondaryColor"; "required": false; }; "secondaryOpacity": { "alias": "secondaryOpacity"; "required": false; }; "title": { "alias": "title"; "required": false; }; }, {}, never, never, true, never>;
|
|
55
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Source of @i316/angular: the one compiled piece of i316's
|
|
2
|
+
// Angular support. Every collection's Angular package is plain icon data that
|
|
3
|
+
// this single directive renders, so using several collections in one template
|
|
4
|
+
// never puts two directives on the same <svg>. Built by build-angular-core.mjs
|
|
5
|
+
// (Angular's compiler in partial mode); the selector list below is generated
|
|
6
|
+
// from scripts/package/collections.mjs.
|
|
7
|
+
import { Directive, ElementRef, InjectionToken, Input, Renderer2, inject } from "@angular/core";
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
export const i316_DEFAULTS = new InjectionToken("i316_DEFAULTS");
|
|
10
|
+
/**
|
|
11
|
+
* Default inputs for every icon in scope. Use in `bootstrapApplication`/route
|
|
12
|
+
* providers for the whole app, or in a component's `providers` for a subtree;
|
|
13
|
+
* nested providers merge over their parent's values.
|
|
14
|
+
*/
|
|
15
|
+
export function providei316(defaults) {
|
|
16
|
+
return {
|
|
17
|
+
provide: i316_DEFAULTS,
|
|
18
|
+
useFactory: () => ({ ...(inject(i316_DEFAULTS, { skipSelf: true, optional: true }) ?? {}), ...defaults }),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const SVG_NS = "svg";
|
|
22
|
+
export class i316 {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.host = inject(ElementRef).nativeElement;
|
|
25
|
+
this.renderer = inject(Renderer2);
|
|
26
|
+
this.defaults = inject(i316_DEFAULTS, { optional: true }) ?? {};
|
|
27
|
+
this.renderedNodes = [];
|
|
28
|
+
this.renderedAttrs = new Set();
|
|
29
|
+
this.renderedClasses = [];
|
|
30
|
+
}
|
|
31
|
+
ngOnChanges() {
|
|
32
|
+
this.render();
|
|
33
|
+
}
|
|
34
|
+
render() {
|
|
35
|
+
const { renderer, host, defaults } = this;
|
|
36
|
+
for (const node of this.renderedNodes)
|
|
37
|
+
renderer.removeChild(host, node);
|
|
38
|
+
for (const name of this.renderedClasses)
|
|
39
|
+
renderer.removeClass(host, name);
|
|
40
|
+
this.renderedNodes = [];
|
|
41
|
+
if (!this.icon)
|
|
42
|
+
return;
|
|
43
|
+
const paint = {
|
|
44
|
+
color: this.color ?? defaults.color ?? "currentColor",
|
|
45
|
+
strokeWidth: this.icon.stroke ? (this.strokeWidth ?? defaults.strokeWidth) : undefined,
|
|
46
|
+
secondary: this.icon.duotone
|
|
47
|
+
? { color: this.secondaryColor ?? defaults.secondaryColor, opacity: this.secondaryOpacity ?? defaults.secondaryOpacity }
|
|
48
|
+
: null,
|
|
49
|
+
};
|
|
50
|
+
const size = String(this.size ?? defaults.size ?? 24);
|
|
51
|
+
const labelled = this.title != null || hostHasOwnLabel(host, this.renderedAttrs);
|
|
52
|
+
const attrs = {
|
|
53
|
+
...resolveAttrs(this.icon.attrs, paint, false),
|
|
54
|
+
width: size,
|
|
55
|
+
height: size,
|
|
56
|
+
...(labelled ? {} : { "aria-hidden": "true" }),
|
|
57
|
+
...(this.title != null ? { role: "img" } : {}),
|
|
58
|
+
};
|
|
59
|
+
for (const name of this.renderedAttrs)
|
|
60
|
+
if (!(name in attrs))
|
|
61
|
+
renderer.removeAttribute(host, name);
|
|
62
|
+
for (const [name, value] of Object.entries(attrs))
|
|
63
|
+
renderer.setAttribute(host, name, value);
|
|
64
|
+
this.renderedAttrs = new Set(Object.keys(attrs));
|
|
65
|
+
this.renderedClasses = [...this.icon.className.split(" "), ...(defaults.className?.split(" ") ?? [])].filter(Boolean);
|
|
66
|
+
for (const name of this.renderedClasses)
|
|
67
|
+
renderer.addClass(host, name);
|
|
68
|
+
if (this.title != null) {
|
|
69
|
+
const title = renderer.createElement("title", SVG_NS);
|
|
70
|
+
renderer.appendChild(title, renderer.createText(this.title));
|
|
71
|
+
this.append(title);
|
|
72
|
+
}
|
|
73
|
+
for (const node of this.icon.nodes)
|
|
74
|
+
this.append(this.createNode(node, paint, false));
|
|
75
|
+
}
|
|
76
|
+
append(node) {
|
|
77
|
+
this.renderer.appendChild(this.host, node);
|
|
78
|
+
this.renderedNodes.push(node);
|
|
79
|
+
}
|
|
80
|
+
createNode([tag, attrs, children], paint, inSecondary) {
|
|
81
|
+
const element = this.renderer.createElement(tag, SVG_NS);
|
|
82
|
+
for (const [name, value] of Object.entries(resolveAttrs(attrs, paint, inSecondary))) {
|
|
83
|
+
this.renderer.setAttribute(element, name, value);
|
|
84
|
+
}
|
|
85
|
+
const secondaryHere = Boolean(paint.secondary) && (inSecondary || attrs["opacity"] != null);
|
|
86
|
+
for (const child of children ?? [])
|
|
87
|
+
this.renderer.appendChild(element, this.createNode(child, paint, secondaryHere));
|
|
88
|
+
return element;
|
|
89
|
+
}
|
|
90
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: i316, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
91
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: i316, isStandalone: true, selector: "svg[i316], svg[solarIcon], svg[phosphorIcon], svg[heroIcon], svg[lucideIcon]", inputs: { icon: "icon", size: "size", color: "color", strokeWidth: "strokeWidth", secondaryColor: "secondaryColor", secondaryOpacity: "secondaryOpacity", title: "title" }, usesOnChanges: true, ngImport: i0 }); }
|
|
92
|
+
}
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: i316, decorators: [{
|
|
94
|
+
type: Directive,
|
|
95
|
+
args: [{
|
|
96
|
+
selector: "svg[i316], svg[solarIcon], svg[phosphorIcon], svg[heroIcon], svg[lucideIcon]",
|
|
97
|
+
standalone: true,
|
|
98
|
+
}]
|
|
99
|
+
}], propDecorators: { icon: [{
|
|
100
|
+
type: Input,
|
|
101
|
+
args: [{ required: true }]
|
|
102
|
+
}], size: [{
|
|
103
|
+
type: Input
|
|
104
|
+
}], color: [{
|
|
105
|
+
type: Input
|
|
106
|
+
}], strokeWidth: [{
|
|
107
|
+
type: Input
|
|
108
|
+
}], secondaryColor: [{
|
|
109
|
+
type: Input
|
|
110
|
+
}], secondaryOpacity: [{
|
|
111
|
+
type: Input
|
|
112
|
+
}], title: [{
|
|
113
|
+
type: Input
|
|
114
|
+
}] } });
|
|
115
|
+
/** An aria-* or role attribute the author set (not one this directive set on a previous render). */
|
|
116
|
+
function hostHasOwnLabel(host, renderedAttrs) {
|
|
117
|
+
for (const { name } of Array.from(host.attributes)) {
|
|
118
|
+
if ((name.startsWith("aria-") || name === "role") && !renderedAttrs.has(name))
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
// `inSecondary`: an ancestor is the translucent layer (e.g. <g opacity="0.5"> wrapping paths).
|
|
124
|
+
function resolveAttrs(attrs, paint, inSecondary) {
|
|
125
|
+
const out = {};
|
|
126
|
+
const isSecondary = Boolean(paint.secondary) && (inSecondary || attrs["opacity"] != null);
|
|
127
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
128
|
+
if ((key === "fill" || key === "stroke") && value === "currentColor") {
|
|
129
|
+
out[key] = isSecondary ? (paint.secondary.color ?? paint.color) : paint.color;
|
|
130
|
+
}
|
|
131
|
+
else if (key === "stroke-width" && paint.strokeWidth != null)
|
|
132
|
+
out[key] = String(paint.strokeWidth);
|
|
133
|
+
else if (key === "opacity" && isSecondary && paint.secondary.opacity != null)
|
|
134
|
+
out[key] = String(paint.secondary.opacity);
|
|
135
|
+
else
|
|
136
|
+
out[key] = value;
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i316/angular",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "i316: the Angular directive that renders every i316 collection.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"i316",
|
|
7
|
+
"icon316",
|
|
8
|
+
"icons",
|
|
9
|
+
"angular",
|
|
10
|
+
"svg"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "rahil316",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./index.js",
|
|
16
|
+
"module": "./index.js",
|
|
17
|
+
"types": "./index.d.ts",
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"files": [
|
|
20
|
+
"LICENSE",
|
|
21
|
+
"README.md",
|
|
22
|
+
"index.d.ts",
|
|
23
|
+
"index.js"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./index.d.ts",
|
|
28
|
+
"default": "./index.js"
|
|
29
|
+
},
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@angular/core": ">=17"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|