diff --git a/.changeset/sweet-dryers-destroy.md b/.changeset/sweet-dryers-destroy.md
new file mode 100644
index 000000000..b511da2c1
--- /dev/null
+++ b/.changeset/sweet-dryers-destroy.md
@@ -0,0 +1,5 @@
+---
+'@openproject/octicons': patch
+---
+
+fix: don't use outerHTML, add specs to Angular package
diff --git a/lib/octicons_angular/package.json b/lib/octicons_angular/package.json
index 476377bcc..ef5269905 100644
--- a/lib/octicons_angular/package.json
+++ b/lib/octicons_angular/package.json
@@ -4,9 +4,10 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
- "build": "script/build.js && ng build",
+ "build": "npm run generate && ng build",
+ "generate": "script/build.js",
"lint": "echo 'No linting specified for @openproject/octicons-angular' && exit 0",
- "test": "echo 'No tests specified for @openproject/octicons-angular' && exit 0",
+ "test": "npm run generate && ng test --no-watch --no-progress --browsers ChromeHeadless",
"watch": "script/build.js && ng build --watch --configuration development"
},
"peerDependencies": {
diff --git a/lib/octicons_angular/script/build.js b/lib/octicons_angular/script/build.js
index fbd4b0677..5d9039218 100755
--- a/lib/octicons_angular/script/build.js
+++ b/lib/octicons_angular/script/build.js
@@ -33,7 +33,9 @@ const icons = Object.entries(octicons)
t.stringLiteral(height),
t.objectExpression([
t.objectProperty(t.stringLiteral('width'), t.numericLiteral(icon.width)),
- t.objectProperty(t.stringLiteral('path'), t.stringLiteral(icon.path))
+ t.objectProperty(t.stringLiteral('paths'), t.arrayExpression(
+ icon.ast.children.map(path => t.stringLiteral(path.attributes.d))
+ ))
])
)
})
@@ -43,18 +45,20 @@ const icons = Object.entries(octicons)
@Component({
selector: 'svg[op-octicon-${key}]',
standalone: true,
- imports: [CommonModule],
+ imports: [NgIf, NgFor],
template: \`
{{title}}
-
+
+
+
\`,
})
export class Op${name} extends OpOcticonComponentBase {
protected override SVGData:{
[key in string]: {
width: number,
- path: string,
+ paths: string[],
};
} = ${generate(svgData).code};
}
@@ -73,7 +77,7 @@ async function writeIconExport(file) {
const count = icons.length
const code = `${GENERATED_HEADER}
import { Component } from '@angular/core';
-import { CommonModule } from '@angular/common';
+import { NgFor, NgIf } from '@angular/common';
import { OpOcticonComponentBase } from '../octicon-component-base';
${icons.map(({code}) => code).join('\n')}
diff --git a/lib/octicons_angular/src/octicon-component-base.ts b/lib/octicons_angular/src/octicon-component-base.ts
index bee5590da..c69e483d8 100644
--- a/lib/octicons_angular/src/octicon-component-base.ts
+++ b/lib/octicons_angular/src/octicon-component-base.ts
@@ -62,14 +62,14 @@ export class OpOcticonComponentBase {
return this.height * (this.naturalWidth / this.naturalHeight);
}
- get path() {
- return this.SVGData[this.naturalHeight].path;
+ get paths() {
+ return this.SVGData[this.naturalHeight].paths;
}
protected SVGData:{
[key in string]: {
width: number,
- path: string,
+ paths: string[],
};
} = {};
diff --git a/lib/octicons_angular/src/public-api.spec.ts b/lib/octicons_angular/src/public-api.spec.ts
new file mode 100644
index 000000000..c67ef156c
--- /dev/null
+++ b/lib/octicons_angular/src/public-api.spec.ts
@@ -0,0 +1,59 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import {
+ OpPlusIcon,
+ OpOpAddIcon,
+} from './public-api';
+
+describe('Github native icon', () => {
+ let component: OpPlusIcon;
+ let fixture: ComponentFixture;
+
+ beforeEach(waitForAsync(() => {
+ TestBed.configureTestingModule({imports: [OpPlusIcon]}).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OpPlusIcon);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeDefined();
+ });
+});
+
+describe('OpenProject extension icon', () => {
+ let component: OpOpAddIcon;
+ let fixture: ComponentFixture;
+
+ beforeEach(waitForAsync(() => {
+ TestBed.configureTestingModule({imports: [OpOpAddIcon]}).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OpOpAddIcon);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeDefined();
+ });
+
+ it('should render the svg', () => {
+ const iconElement: HTMLElement = fixture.nativeElement;
+ expect(iconElement.children[0].tagName.toLowerCase()).toEqual("path");
+ });
+
+ it('should render the title', () => {
+ const iconElement: HTMLElement = fixture.nativeElement;
+ expect(iconElement.children[0].tagName.toLowerCase()).toEqual("path");
+
+ component.title = "Some title";
+ fixture.detectChanges();
+
+ expect(iconElement.children[0].tagName.toLowerCase()).toEqual("title");
+ expect(iconElement.children[1].tagName.toLowerCase()).toEqual("path");
+ });
+});
diff --git a/lib/octicons_jekyll/Gemfile b/lib/octicons_jekyll/Gemfile
index 6e4200833..303f2f47c 100644
--- a/lib/octicons_jekyll/Gemfile
+++ b/lib/octicons_jekyll/Gemfile
@@ -2,7 +2,7 @@ source "https://rubygems.org"
gemspec
-gem "openproject-octicons", "19.6.0"
+gem "openproject-octicons", "19.6.1"
group :development, :test do
gem "minitest"