Skip to content

Commit cbee382

Browse files
committed
chore: use signal
1 parent 93a1f5c commit cbee382

File tree

8 files changed

+79
-83
lines changed

8 files changed

+79
-83
lines changed

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"editor.formatOnSave": true,
3+
"editor.codeActionsOnSave": {
4+
"source.fixAll.eslint": "explicit",
5+
"source.fixAll.stylelint": "explicit"
6+
}
7+
}

README.md

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# ngx-highlight-js
2+
23
Angular for syntax highlighting with highlight.js
34

45
[![NPM version](https://img.shields.io/npm/v/ngx-highlight-js.svg)](https://www.npmjs.com/package/ngx-highlight-js)
@@ -29,29 +30,13 @@ Load the [highlight.js](https://highlightjs.org/download/) and theme css in page
2930

3031
## Usage
3132

32-
**NgModule**
33-
34-
Import the `HighlightJsModule` in to your root `AppModule`.
35-
36-
```typescript
37-
import { HighlightJsModule } from 'ngx-highlight-js';
38-
@NgModule({
39-
imports: [ HighlightJsModule ],
40-
bootstrap: [AppComponent]
41-
})
42-
export class AppModule {
43-
}
44-
```
45-
46-
**Standalone**
47-
4833
```typescript
4934
import { Component } from '@angular/core';
5035
import { HighlightJsDirective } from 'ngx-highlight-js';
36+
5137
@Component({
5238
selector: 'test',
5339
template: `<textarea highlight-js [lang]="'bash'">npm install --save ngx-highlight-js</textarea>`,
54-
standalone: true,
5540
imports: [HighlightJsDirective],
5641
})
5742
export class SimpleComponent {}
@@ -101,26 +86,18 @@ Will render each `<pre><code>`:
10186

10287
### Parameter
10388

104-
| Property | Description | Type | Default | Global Config |
105-
|----------|-------------|------|---------|---------------|
106-
| `[mode]` | - `default` Will render each `<pre><code>`<br>- `simple` Render all content according to `lang` language | `default, simple` | `simple` ||
107-
| `[options]` | Equar [configure(options)](https://highlightjs.readthedocs.io/en/latest/api.html#configure) | `any` | - ||
108-
| `[lang]` | Uses language detection by default but you can specify the language | `string` | `html` ||
109-
| `[code]` | Specify content | `string` | `html` | - |
89+
| Property | Description | Type | Default | Global Config |
90+
| ----------- | -------------------------------------------------------------------------------------------------------- | ----------------- | -------- | ------------- |
91+
| `[mode]` | - `default` Will render each `<pre><code>`<br>- `simple` Render all content according to `lang` language | `default, simple` | `simple` | |
92+
| `[options]` | Equar [configure(options)](https://highlightjs.readthedocs.io/en/latest/api.html#configure) | `any` | - | |
93+
| `[lang]` | Uses language detection by default but you can specify the language | `string` | `html` | |
94+
| `[code]` | Specify content | `string` | `html` | - |
11095

11196
**Global Config**
11297

11398
```ts
11499
@NgModule({
115-
providers: [
116-
{
117-
provide: HIGHLIGHTJS_CONFIG,
118-
useValue: {
119-
lang: 'html'
120-
} as HighlightJsConfig
121-
}
122-
],
123-
imports: [ HighlightJsModule ],
100+
providers: [provideSFConfig({ lang: 'html' })],
124101
})
125102
export class AppDemoModule {}
126103
```

lib/src/highlight-js.config.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { InjectionToken } from '@angular/core';
1+
import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders, Provider } from '@angular/core';
22
import type { HLJSOptions } from 'highlight.js';
33

44
export interface HighlightJsConfig {
@@ -19,3 +19,16 @@ export interface HighlightJsConfig {
1919
}
2020

2121
export const HIGHLIGHTJS_CONFIG = new InjectionToken<HighlightJsConfig>('HighlightJs-Config');
22+
23+
export function provideSFConfig(options: Partial<HighlightJsConfig>): EnvironmentProviders {
24+
const provides: Array<Provider | EnvironmentProviders> = [
25+
{
26+
provide: HIGHLIGHTJS_CONFIG,
27+
useValue: {
28+
lang: 'html',
29+
...options,
30+
} as HighlightJsConfig,
31+
},
32+
];
33+
return makeEnvironmentProviders(provides);
34+
}

lib/src/highlight-js.directive.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,37 @@
1-
import { Directive, ElementRef, Input, OnDestroy, AfterViewInit, Inject, Optional, NgZone } from '@angular/core';
1+
import { Directive, ElementRef, OnDestroy, AfterViewInit, NgZone, input, model, inject } from '@angular/core';
22
import { DOCUMENT } from '@angular/common';
33
import { NgModel } from '@angular/forms';
44
import { Subscription } from 'rxjs';
5-
import { HighlightJsConfig, HIGHLIGHTJS_CONFIG } from './highlight-js.config';
5+
import { HIGHLIGHTJS_CONFIG } from './highlight-js.config';
66
import type { HLJSApi, HLJSOptions } from 'highlight.js';
77

88
declare const ngDevMode: boolean;
99

1010
@Directive({
1111
selector: '[highlight-js]',
1212
host: {
13-
'[style.display]': `mode === 'simple' ? 'none' : null`,
13+
'[style.display]': `mode() === 'simple' ? 'none' : null`,
1414
},
1515
exportAs: 'highlightJs',
16-
standalone: true,
1716
})
1817
export class HighlightJsDirective implements AfterViewInit, OnDestroy {
19-
@Input() options?: Partial<HLJSOptions>;
20-
@Input() lang = 'html';
21-
@Input() code?: string;
22-
@Input() mode: 'default' | 'simple' = 'simple';
18+
readonly options = input<Partial<HLJSOptions>>();
19+
readonly l = input<string>('html', { alias: 'lang'});
20+
readonly code = model<string>();
21+
readonly mode = input<'default' | 'simple'>('simple');
2322

2423
protected codeEl?: HTMLElement;
2524
protected parentEl?: HTMLElement;
2625
private modelValue$?: Subscription;
2726
private observer?: MutationObserver;
27+
private el = inject<ElementRef<HTMLElement>>(ElementRef);
28+
private ngModel = inject<NgModel>(NgModel, {optional: true});
29+
private doc = inject(DOCUMENT);
30+
private cog = inject(HIGHLIGHTJS_CONFIG, {optional: true});
31+
private ngZone = inject(NgZone);
2832

29-
constructor(
30-
private el: ElementRef<HTMLElement>,
31-
@Optional() private ngModel: NgModel,
32-
@Inject(DOCUMENT) private doc: any,
33-
@Optional() @Inject(HIGHLIGHTJS_CONFIG) cog: HighlightJsConfig,
34-
private ngZone: NgZone,
35-
) {
36-
Object.assign(this, cog);
33+
constructor() {
34+
Object.assign(this, this.cog);
3735
}
3836

3937
private escapeHTML(str: string): string {
@@ -44,15 +42,16 @@ export class HighlightJsDirective implements AfterViewInit, OnDestroy {
4442
this.ngZone.runOutsideAngular(() => {
4543
this.destroy();
4644
const el = this.el.nativeElement;
47-
const code = this.code || '' + el.innerHTML.trim();
45+
const code = this.code() ?? '' + el.innerHTML.trim();
4846
const doc = this.doc as Document;
49-
this.codeEl = doc.createElement(this.mode === 'default' ? 'div' : 'pre') as HTMLElement;
47+
this.codeEl = doc.createElement(this.mode() === 'default' ? 'div' : 'pre') as HTMLElement;
5048
if (this.codeEl == null) return;
5149

52-
const isSimple = this.mode === 'simple';
50+
const isSimple = this.mode() === 'simple';
5351
if (isSimple) {
54-
if (this.lang) {
55-
this.codeEl.className = this.lang;
52+
const lang = this.l();
53+
if (lang) {
54+
this.codeEl.className = lang;
5655
}
5756
this.parentEl = el.parentNode as HTMLElement;
5857
this.parentEl.insertBefore(this.codeEl, el.nextSibling);
@@ -70,7 +69,7 @@ export class HighlightJsDirective implements AfterViewInit, OnDestroy {
7069
return;
7170
}
7271

73-
hljs.configure({ ...this.options });
72+
hljs.configure({ ...this.options() });
7473

7574
if (isSimple) {
7675
hljs.highlightElement(this.codeEl);
@@ -93,7 +92,7 @@ export class HighlightJsDirective implements AfterViewInit, OnDestroy {
9392
this.init();
9493
if (this.ngModel) {
9594
this.modelValue$ = this.ngModel.valueChanges?.subscribe((res) => {
96-
this.code = this.escapeHTML(res);
95+
this.code.set(this.escapeHTML(res));
9796
this.init();
9897
});
9998
} else {

package.json

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,40 +28,42 @@
2828
"release:next": "npm run build && cd publish && npm publish --access public --tag next"
2929
},
3030
"dependencies": {
31-
"@angular/animations": "^18.0.0",
32-
"@angular/common": "^18.0.0",
33-
"@angular/compiler": "^18.0.0",
34-
"@angular/core": "^18.0.0",
35-
"@angular/forms": "^18.0.0",
36-
"@angular/platform-browser": "^18.0.0",
37-
"@angular/platform-browser-dynamic": "^18.0.0",
38-
"@angular/router": "^18.0.0",
39-
"highlight.js": "^11.0.0",
31+
"@angular/animations": "^19.0.0",
32+
"@angular/common": "^19.0.0",
33+
"@angular/compiler": "^19.0.0",
34+
"@angular/core": "^19.0.0",
35+
"@angular/forms": "^19.0.0",
36+
"@angular/platform-browser": "^19.0.0",
37+
"@angular/platform-browser-dynamic": "^19.0.0",
38+
"@angular/router": "^19.0.0",
39+
"highlight.js": "^11.10.0",
4040
"rxjs": "~7.8.0",
4141
"tslib": "^2.3.0",
42-
"zone.js": "~0.14.3"
42+
"zone.js": "~0.15.0"
4343
},
4444
"devDependencies": {
45-
"@angular-devkit/build-angular": "^18.0.4",
46-
"@angular-eslint/builder": "^18.0.0",
47-
"@angular-eslint/eslint-plugin": "^18.0.0",
48-
"@angular-eslint/eslint-plugin-template": "^18.0.0",
49-
"@angular-eslint/schematics": "^18.0.0",
50-
"@angular-eslint/template-parser": "^18.0.0",
51-
"@angular/cli": "^18.0.4",
52-
"@angular/compiler-cli": "^18.0.0",
45+
"@angular-devkit/build-angular": "^19.0.1",
46+
"@angular-eslint/builder": "^18.4.1",
47+
"@angular-eslint/eslint-plugin": "^18.4.1",
48+
"@angular-eslint/eslint-plugin-template": "^18.4.1",
49+
"@angular-eslint/schematics": "^18.4.1",
50+
"@angular-eslint/template-parser": "^18.4.1",
51+
"@angular/cli": "^19.0.1",
52+
"@angular/compiler-cli": "^19.0.0",
53+
"@types/file-saver": "^2.0.7",
5354
"@types/jasmine": "~5.1.0",
54-
"@typescript-eslint/eslint-plugin": "^7.13.0",
55-
"@typescript-eslint/parser": "^7.13.0",
55+
"@typescript-eslint/eslint-plugin": "^8.15.0",
56+
"@typescript-eslint/parser": "^8.15.0",
5657
"eslint": "^8.53.0",
57-
"jasmine-core": "~5.1.0",
58+
"file-saver": "^2.0.5",
59+
"jasmine-core": "~5.4.0",
5860
"karma": "~6.4.0",
5961
"karma-chrome-launcher": "~3.2.0",
6062
"karma-coverage": "~2.2.0",
6163
"karma-jasmine": "~5.1.0",
6264
"karma-jasmine-html-reporter": "~2.1.0",
63-
"ng-packagr": "^18.0.0",
64-
"typescript": "~5.4.2"
65+
"ng-packagr": "^19.0.1",
66+
"typescript": "~5.6.2"
6567
},
6668
"packageManager": "[email protected]"
6769
}

src/app/app.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { DemoComponent } from './components/demo.component';
99
<demo></demo>
1010
`,
1111
encapsulation: ViewEncapsulation.None,
12-
standalone: true,
1312
imports: [DemoComponent],
1413
})
1514
export class AppComponent {}

src/app/components/demo.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const r = (min: number, max: number) => Math.floor(Math.random() * (max - min +
99
@Component({
1010
selector: 'demo',
1111
templateUrl: './demo.component.html',
12-
standalone: true,
1312
imports: [CommonModule, FormsModule, HighlightJsDirective],
1413
})
1514
export class DemoComponent implements OnInit {

src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { bootstrapApplication } from '@angular/platform-browser';
22
import { AppComponent } from './app/app.component';
3-
import { HighlightJsConfig, HIGHLIGHTJS_CONFIG } from 'ngx-highlight-js';
3+
import { provideSFConfig } from 'ngx-highlight-js';
44

55
bootstrapApplication(AppComponent, {
6-
providers: [{ provide: HIGHLIGHTJS_CONFIG, useValue: { lang: 'html' } as HighlightJsConfig }],
6+
providers: [provideSFConfig({ lang: 'html' })],
77
}).catch((err) => console.error(err));

0 commit comments

Comments
 (0)