@mathstack/app-kit 2.1.0 → 2.2.1
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 -21
- package/README.md +36 -36
- package/{src/lib/baseline-styles → baseline-styles}/_css-reset.scss +118 -118
- package/{src/lib/baseline-styles → baseline-styles}/_grid.scss +4 -4
- package/{src/lib/baseline-styles → baseline-styles}/_index.scss +6 -6
- package/{src/lib/baseline-styles → baseline-styles}/_sass-utils.scss +23 -23
- package/{src/lib/baseline-styles → baseline-styles}/_themes.scss +19 -19
- package/{src/lib/baseline-styles → baseline-styles}/_typography.scss +232 -232
- package/{src/lib/baseline-styles → baseline-styles}/_webkit-scrollbar.scss +22 -22
- package/{src/lib/baseline-styles → baseline-styles}/theming/_colors.scss +46 -46
- package/{src/lib/baseline-styles → baseline-styles}/theming/_index.scss +2 -2
- package/{src/lib/baseline-styles → baseline-styles}/theming/_typography.scss +32 -32
- package/fesm2022/mathstack-app-kit.mjs +843 -0
- package/fesm2022/mathstack-app-kit.mjs.map +1 -0
- package/package.json +14 -7
- package/types/mathstack-app-kit.d.ts +394 -0
- package/.eslintrc.json +0 -34
- package/ng-package.json +0 -15
- package/project.json +0 -76
- package/src/lib/assets/assets-resource.ts +0 -18
- package/src/lib/assets/assets-service.spec.ts +0 -54
- package/src/lib/assets/assets-service.ts +0 -73
- package/src/lib/assets/index.ts +0 -2
- package/src/lib/content-parsing/index.ts +0 -2
- package/src/lib/content-parsing/markdown-parser.ts +0 -197
- package/src/lib/content-parsing/shiki-highlighter.ts +0 -219
- package/src/lib/core/scss/_colors.scss +0 -37
- package/src/lib/core/scss/_functions.scss +0 -4
- package/src/lib/core/scss/_placeholders.scss +0 -1
- package/src/lib/core/scss/_vars.scss +0 -15
- package/src/lib/core/testing/stubs/services/assets.resource.stub.ts +0 -3
- package/src/lib/core/testing/stubs/services/main.service.stub.ts +0 -5
- package/src/lib/core/utilities/deep-merge.spec.ts +0 -29
- package/src/lib/core/utilities/deep-merge.ts +0 -21
- package/src/lib/core/utilities/index.ts +0 -2
- package/src/lib/core/utilities/safe-assign.spec.ts +0 -41
- package/src/lib/core/utilities/safe-assign.ts +0 -42
- package/src/lib/documentation-display/active-heading-tracker.ts +0 -61
- package/src/lib/documentation-display/document-index/document-index.component.html +0 -34
- package/src/lib/documentation-display/document-index/document-index.component.scss +0 -56
- package/src/lib/documentation-display/document-index/document-index.component.spec.ts +0 -0
- package/src/lib/documentation-display/document-index/document-index.component.ts +0 -39
- package/src/lib/documentation-display/documentation-config-parser.ts +0 -92
- package/src/lib/documentation-display/documentation-content-service.ts +0 -118
- package/src/lib/documentation-display/documentation-display.component.html +0 -33
- package/src/lib/documentation-display/documentation-display.component.scss +0 -142
- package/src/lib/documentation-display/documentation-display.component.spec.ts +0 -0
- package/src/lib/documentation-display/documentation-display.component.ts +0 -129
- package/src/lib/documentation-display/index.ts +0 -6
- package/src/lib/documentation-display/navigation-siblings/navigation-siblings.component.html +0 -31
- package/src/lib/documentation-display/navigation-siblings/navigation-siblings.component.scss +0 -68
- package/src/lib/documentation-display/navigation-siblings/navigation-siblings.component.spec.ts +0 -0
- package/src/lib/documentation-display/navigation-siblings/navigation-siblings.component.ts +0 -52
- package/src/lib/ng-utilities/index.ts +0 -2
- package/src/lib/ng-utilities/ng-on-changes.spec.ts +0 -117
- package/src/lib/ng-utilities/ng-on-changes.ts +0 -50
- package/src/lib/ng-utilities/run-ng-change-detection-then.ts +0 -40
- package/src/public-api.ts +0 -6
- package/tsconfig.lib.json +0 -16
- package/tsconfig.lib.prod.json +0 -11
- package/tsconfig.spec.json +0 -10
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
@use '../baseline-styles/grid' as *;
|
|
2
|
-
@use '../core/scss/placeholders' as *;
|
|
3
|
-
@use '../core/scss/vars' as *;
|
|
4
|
-
@use '../core/scss/colors';
|
|
5
|
-
|
|
6
|
-
.documentation-container {
|
|
7
|
-
margin: 0 auto;
|
|
8
|
-
max-width: 1200px;
|
|
9
|
-
|
|
10
|
-
.documentation-content {
|
|
11
|
-
display: flex;
|
|
12
|
-
gap: grid(30);
|
|
13
|
-
margin-top: grid(6);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.document-index {
|
|
17
|
-
$top: grid(32);
|
|
18
|
-
display: block;
|
|
19
|
-
position: sticky;
|
|
20
|
-
top: $top;
|
|
21
|
-
max-height: calc(100vh - $top - grid(8));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.main-content {
|
|
25
|
-
width: 75%;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.nav-siblings {
|
|
29
|
-
padding-top: grid(10);
|
|
30
|
-
padding-bottom: grid(20);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.injected-html {
|
|
34
|
-
h1 {
|
|
35
|
-
@include headline-large;
|
|
36
|
-
margin: 0 0 grid(7) 0;
|
|
37
|
-
width: 100%;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
h2 {
|
|
41
|
-
@include headline-small;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
h3 {
|
|
45
|
-
@include label-large;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
h2,
|
|
49
|
-
h3,
|
|
50
|
-
h4 {
|
|
51
|
-
margin: 0;
|
|
52
|
-
padding-top: grid(4);
|
|
53
|
-
padding-bottom: grid(6);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
p {
|
|
57
|
-
padding-bottom: grid(6);
|
|
58
|
-
line-height: 1.8;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
ol {
|
|
62
|
-
margin: 0;
|
|
63
|
-
padding-bottom: grid(6);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
li > p:not(.code-caption) {
|
|
67
|
-
padding-bottom: grid(4);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
pre {
|
|
71
|
-
margin: 0;
|
|
72
|
-
padding-bottom: grid(6);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
a {
|
|
76
|
-
cursor: pointer;
|
|
77
|
-
color: colors.$primary-40;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
a:hover {
|
|
81
|
-
text-decoration: underline;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.shiki {
|
|
85
|
-
margin: 0;
|
|
86
|
-
padding: grid(4);
|
|
87
|
-
border: 1px solid colors.$muted-primary-90;
|
|
88
|
-
border-radius: grid(2);
|
|
89
|
-
margin-bottom: grid(8);
|
|
90
|
-
white-space: pre-wrap;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
p.code-caption {
|
|
94
|
-
margin-bottom: 0;
|
|
95
|
-
padding-bottom: 0;
|
|
96
|
-
font-style: italic;
|
|
97
|
-
|
|
98
|
-
code {
|
|
99
|
-
font-style: normal;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
p.code-caption + pre.shiki {
|
|
104
|
-
display: block;
|
|
105
|
-
margin-top: 2px;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
p:has(> code) + hr {
|
|
109
|
-
margin: 0;
|
|
110
|
-
border-top: 1px solid colors.$muted-primary-80;
|
|
111
|
-
margin-bottom: grid(6);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
P:has(> code):has(+ hr) {
|
|
115
|
-
padding-bottom: grid(2);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
h1 > code,
|
|
119
|
-
h2 > code,
|
|
120
|
-
h3 > code,
|
|
121
|
-
h4 > code,
|
|
122
|
-
h5 > code,
|
|
123
|
-
h6 > code,
|
|
124
|
-
li > code,
|
|
125
|
-
li > em > code,
|
|
126
|
-
p > code p > em > code {
|
|
127
|
-
font-family: $font-mono;
|
|
128
|
-
font-weight: 500;
|
|
129
|
-
padding-left: grid(1);
|
|
130
|
-
padding-right: grid(1);
|
|
131
|
-
background: colors.$muted-primary-95;
|
|
132
|
-
border-radius: grid(1);
|
|
133
|
-
color: colors.$primary-40;
|
|
134
|
-
padding: grid(0.5) grid(1);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
p > code,
|
|
138
|
-
p > em > code {
|
|
139
|
-
font-size: 15px;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
File without changes
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { CommonModule, DOCUMENT } from '@angular/common';
|
|
2
|
-
import {
|
|
3
|
-
AfterViewInit,
|
|
4
|
-
ChangeDetectionStrategy,
|
|
5
|
-
Component,
|
|
6
|
-
ContentChild,
|
|
7
|
-
DestroyRef,
|
|
8
|
-
ElementRef,
|
|
9
|
-
EventEmitter,
|
|
10
|
-
inject,
|
|
11
|
-
Input,
|
|
12
|
-
NgZone,
|
|
13
|
-
OnInit,
|
|
14
|
-
Output,
|
|
15
|
-
TemplateRef,
|
|
16
|
-
ViewChild,
|
|
17
|
-
ViewEncapsulation,
|
|
18
|
-
} from '@angular/core';
|
|
19
|
-
import { Observable } from 'rxjs';
|
|
20
|
-
import { ShikiTheme } from '../content-parsing';
|
|
21
|
-
import { AdkActiveHeadingTracker } from './active-heading-tracker';
|
|
22
|
-
import { AdkDocumentIndexComponent } from './document-index/document-index.component';
|
|
23
|
-
import { AdkNestedObject } from './documentation-config-parser';
|
|
24
|
-
import {
|
|
25
|
-
AdkDocumentationContentService,
|
|
26
|
-
AdkHtmlHeader,
|
|
27
|
-
AdkParsedDocumentation,
|
|
28
|
-
} from './documentation-content-service';
|
|
29
|
-
import { NavigationSiblingsComponent } from './navigation-siblings/navigation-siblings.component';
|
|
30
|
-
|
|
31
|
-
@Component({
|
|
32
|
-
selector: 'hsi-adk-documentation-display',
|
|
33
|
-
imports: [
|
|
34
|
-
CommonModule,
|
|
35
|
-
AdkDocumentIndexComponent,
|
|
36
|
-
NavigationSiblingsComponent,
|
|
37
|
-
],
|
|
38
|
-
templateUrl: './documentation-display.component.html',
|
|
39
|
-
styleUrls: ['./documentation-display.component.scss'],
|
|
40
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
41
|
-
encapsulation: ViewEncapsulation.None,
|
|
42
|
-
})
|
|
43
|
-
export class AdkDocumentationDisplayComponent implements OnInit, AfterViewInit {
|
|
44
|
-
/**
|
|
45
|
-
* Observable that emits the current content path
|
|
46
|
-
*/
|
|
47
|
-
@Input() contentPath$: Observable<string>;
|
|
48
|
-
@Input() fileConfig: AdkNestedObject;
|
|
49
|
-
@Input() highlightTheme: ShikiTheme;
|
|
50
|
-
@Input() pathFromAssetsToFile: string;
|
|
51
|
-
@Input() showPrevNextNavigation = true;
|
|
52
|
-
@Output() nextDoc: EventEmitter<string> = new EventEmitter<string>();
|
|
53
|
-
@ViewChild('file') file: ElementRef<HTMLDivElement>;
|
|
54
|
-
content$: Observable<AdkParsedDocumentation>;
|
|
55
|
-
@ContentChild('escapedContent', { static: false })
|
|
56
|
-
escapedContentTemplateRef: TemplateRef<unknown>;
|
|
57
|
-
|
|
58
|
-
private content = inject(AdkDocumentationContentService);
|
|
59
|
-
private activeHeading = inject(AdkActiveHeadingTracker);
|
|
60
|
-
private destroyRef = inject(DestroyRef);
|
|
61
|
-
private zone = inject(NgZone);
|
|
62
|
-
private document = inject(DOCUMENT);
|
|
63
|
-
|
|
64
|
-
ngOnInit(): void {
|
|
65
|
-
this.setContent();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
ngAfterViewInit(): void {
|
|
69
|
-
this.activeHeading.initScrollListener(
|
|
70
|
-
this.file.nativeElement,
|
|
71
|
-
this.destroyRef
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
setContent(): void {
|
|
76
|
-
this.content$ = this.content.getContentForCurrentContentPath(
|
|
77
|
-
this.contentPath$,
|
|
78
|
-
{
|
|
79
|
-
fileConfig: this.fileConfig,
|
|
80
|
-
basePath: this.pathFromAssetsToFile,
|
|
81
|
-
parsingOptions: {
|
|
82
|
-
highlighter: {
|
|
83
|
-
theme: this.highlightTheme,
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
}
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
scrollToHeading(update: {
|
|
91
|
-
heading: AdkHtmlHeader;
|
|
92
|
-
event: KeyboardEvent | PointerEvent | MouseEvent | Event;
|
|
93
|
-
}): void {
|
|
94
|
-
const targetHeading = this.file.nativeElement.querySelector(
|
|
95
|
-
`#${update.heading.id}`
|
|
96
|
-
) as HTMLHeadingElement;
|
|
97
|
-
targetHeading.focus();
|
|
98
|
-
this.scrollToItemById(
|
|
99
|
-
targetHeading,
|
|
100
|
-
(update.event as KeyboardEvent).key === 'Enter'
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
scrollToItemById(
|
|
105
|
-
item: HTMLHeadingElement,
|
|
106
|
-
needsChangeDetection = false
|
|
107
|
-
): void {
|
|
108
|
-
this.activeHeading.setActiveHeading(item as HTMLHeadingElement);
|
|
109
|
-
const currentOffset = item.offsetTop;
|
|
110
|
-
if (needsChangeDetection) {
|
|
111
|
-
this.zone.run(() => {
|
|
112
|
-
this.scrollToItem(currentOffset);
|
|
113
|
-
});
|
|
114
|
-
} else {
|
|
115
|
-
this.scrollToItem(currentOffset);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
scrollToItem(top: number): void {
|
|
120
|
-
this.document.getElementsByTagName('HTML')[0].scrollTo({
|
|
121
|
-
top,
|
|
122
|
-
behavior: 'smooth',
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
navigateToDoc(sibling: string): void {
|
|
127
|
-
this.nextDoc.emit(sibling);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export * from './active-heading-tracker';
|
|
2
|
-
export * from './document-index/document-index.component';
|
|
3
|
-
export * from './documentation-config-parser';
|
|
4
|
-
export * from './documentation-content-service';
|
|
5
|
-
export * from './documentation-display.component';
|
|
6
|
-
export * from './navigation-siblings/navigation-siblings.component';
|
package/src/lib/documentation-display/navigation-siblings/navigation-siblings.component.html
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
@if (siblings.previous) {
|
|
2
|
-
<div
|
|
3
|
-
class="nav-panel previous"
|
|
4
|
-
role="link"
|
|
5
|
-
tabindex="0"
|
|
6
|
-
(click)="navigateToDoc(siblings.previous)"
|
|
7
|
-
(keydown.enter)="navigateToDoc(siblings.previous)"
|
|
8
|
-
><p class="label">Previous</p
|
|
9
|
-
><p class="name"
|
|
10
|
-
><span aria-hidden="true" class="material-symbols-outlined arrow"
|
|
11
|
-
>arrow_back</span
|
|
12
|
-
>{{ previous }}</p
|
|
13
|
-
></div
|
|
14
|
-
>
|
|
15
|
-
}
|
|
16
|
-
@if (siblings.next) {
|
|
17
|
-
<div
|
|
18
|
-
class="nav-panel next"
|
|
19
|
-
role="link"
|
|
20
|
-
tabindex="0"
|
|
21
|
-
(click)="navigateToDoc(siblings.next)"
|
|
22
|
-
(keydown.enter)="navigateToDoc(siblings.next)"
|
|
23
|
-
><p class="label">Next</p
|
|
24
|
-
><p class="name"
|
|
25
|
-
>{{ next }}
|
|
26
|
-
<span aria-hidden="true" class="material-symbols-outlined arrow"
|
|
27
|
-
>arrow_forward</span
|
|
28
|
-
></p
|
|
29
|
-
></div
|
|
30
|
-
>
|
|
31
|
-
}
|
package/src/lib/documentation-display/navigation-siblings/navigation-siblings.component.scss
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
@use '../../baseline-styles/grid' as *;
|
|
2
|
-
@use '../../core/scss/placeholders' as *;
|
|
3
|
-
@use '../../core/scss/colors';
|
|
4
|
-
|
|
5
|
-
:host {
|
|
6
|
-
display: grid;
|
|
7
|
-
grid-template-columns: 1fr 1fr;
|
|
8
|
-
grid-template-areas: 'previous next';
|
|
9
|
-
gap: grid(4);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.nav-panel {
|
|
13
|
-
border: 1px solid colors.$muted-primary-80;
|
|
14
|
-
padding: grid(4);
|
|
15
|
-
border-radius: grid(2);
|
|
16
|
-
cursor: pointer;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.nav-panel:hover {
|
|
20
|
-
background: colors.$primary-98;
|
|
21
|
-
border: 1px solid colors.$primary-70;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.nav-panel.previous {
|
|
25
|
-
grid-area: previous;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.nav-panel.next {
|
|
29
|
-
grid-area: next;
|
|
30
|
-
text-align: right;
|
|
31
|
-
|
|
32
|
-
.name {
|
|
33
|
-
justify-content: flex-end;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.label {
|
|
37
|
-
justify-content: flex-end;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.label {
|
|
42
|
-
@include label-2xs-caps;
|
|
43
|
-
line-height: 1;
|
|
44
|
-
display: flex;
|
|
45
|
-
align-items: center;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.name {
|
|
49
|
-
display: flex;
|
|
50
|
-
align-items: center;
|
|
51
|
-
position: relative;
|
|
52
|
-
padding-top: grid(2);
|
|
53
|
-
color: colors.$primary-40;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.arrow {
|
|
57
|
-
transform: scale(0.8);
|
|
58
|
-
position: relative;
|
|
59
|
-
top: -1px;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.previous .name {
|
|
63
|
-
left: -6px;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.next .name {
|
|
67
|
-
right: -6px;
|
|
68
|
-
}
|
package/src/lib/documentation-display/navigation-siblings/navigation-siblings.component.spec.ts
DELETED
|
File without changes
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { CommonModule, TitleCasePipe } from '@angular/common';
|
|
2
|
-
import {
|
|
3
|
-
ChangeDetectionStrategy,
|
|
4
|
-
Component,
|
|
5
|
-
EventEmitter,
|
|
6
|
-
inject,
|
|
7
|
-
Input,
|
|
8
|
-
OnChanges,
|
|
9
|
-
Output,
|
|
10
|
-
} from '@angular/core';
|
|
11
|
-
import { AdkDocumentationNavigationSiblings } from '../documentation-config-parser';
|
|
12
|
-
|
|
13
|
-
@Component({
|
|
14
|
-
selector: 'hsi-adk-navigation-siblings',
|
|
15
|
-
imports: [CommonModule],
|
|
16
|
-
providers: [TitleCasePipe],
|
|
17
|
-
templateUrl: './navigation-siblings.component.html',
|
|
18
|
-
styleUrls: ['./navigation-siblings.component.scss'],
|
|
19
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
20
|
-
})
|
|
21
|
-
export class NavigationSiblingsComponent implements OnChanges {
|
|
22
|
-
@Input() siblings: AdkDocumentationNavigationSiblings;
|
|
23
|
-
@Output() nextDoc: EventEmitter<string> = new EventEmitter<string>();
|
|
24
|
-
previous: string;
|
|
25
|
-
next: string;
|
|
26
|
-
|
|
27
|
-
private titleCase = inject(TitleCasePipe);
|
|
28
|
-
|
|
29
|
-
ngOnChanges(): void {
|
|
30
|
-
this.setDisplayNames();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
setDisplayNames(): void {
|
|
34
|
-
this.previous = this.siblings.previous
|
|
35
|
-
? this.getDisplayName(this.siblings.previous)
|
|
36
|
-
: undefined;
|
|
37
|
-
this.next = this.siblings.next
|
|
38
|
-
? this.getDisplayName(this.siblings.next)
|
|
39
|
-
: undefined;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
getDisplayName(path: string): string {
|
|
43
|
-
const paths = path.split('/');
|
|
44
|
-
const end = paths[paths.length - 1];
|
|
45
|
-
const dehyphenated = end.replace(/-/g, ' ');
|
|
46
|
-
return this.titleCase.transform(dehyphenated);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
navigateToDoc(sibling: string): void {
|
|
50
|
-
this.nextDoc.emit(sibling);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { SimpleChange } from '@angular/core';
|
|
3
|
-
import { NgOnChangesUtilities } from './ng-on-changes';
|
|
4
|
-
|
|
5
|
-
describe('ngInputObjectChangedNotFirstTime()', () => {
|
|
6
|
-
let ngInputObjectChanged: jasmine.Spy;
|
|
7
|
-
let changes: any;
|
|
8
|
-
let inputName: string;
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
ngInputObjectChanged = spyOn(
|
|
11
|
-
NgOnChangesUtilities,
|
|
12
|
-
'inputObjectChanged'
|
|
13
|
-
).and.returnValue(true);
|
|
14
|
-
inputName = 'test';
|
|
15
|
-
changes = {
|
|
16
|
-
[inputName]: {
|
|
17
|
-
previousValue: '',
|
|
18
|
-
currentValue: '',
|
|
19
|
-
isFirstChange: () => false,
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe('if input has changed', () => {
|
|
25
|
-
describe('if it is not the first change', () => {
|
|
26
|
-
it('returns true if objectChanges returns true', () => {
|
|
27
|
-
const result = NgOnChangesUtilities.inputObjectChangedNotFirstTime(
|
|
28
|
-
changes,
|
|
29
|
-
inputName
|
|
30
|
-
);
|
|
31
|
-
expect(result).toEqual(true);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('returns false if objectOnNgChanges returns false', () => {
|
|
35
|
-
ngInputObjectChanged.and.returnValue(false);
|
|
36
|
-
const result = NgOnChangesUtilities.inputObjectChangedNotFirstTime(
|
|
37
|
-
changes,
|
|
38
|
-
inputName
|
|
39
|
-
);
|
|
40
|
-
expect(result).toEqual(false);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('returns false if it is the first change', () => {
|
|
45
|
-
changes[inputName].isFirstChange = () => true;
|
|
46
|
-
const result = NgOnChangesUtilities.inputObjectChangedNotFirstTime(
|
|
47
|
-
changes,
|
|
48
|
-
inputName
|
|
49
|
-
);
|
|
50
|
-
expect(result).toEqual(false);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('returns false if changes does not have property for input string', () => {
|
|
55
|
-
changes = { wrong: new SimpleChange('', '', false) };
|
|
56
|
-
const result = NgOnChangesUtilities.inputObjectChangedNotFirstTime(
|
|
57
|
-
changes,
|
|
58
|
-
inputName
|
|
59
|
-
);
|
|
60
|
-
expect(result).toEqual(false);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe('ngInputObjectChanged()', () => {
|
|
65
|
-
let changes: any;
|
|
66
|
-
let objectName: string;
|
|
67
|
-
let prevObj: any;
|
|
68
|
-
let currObj: any;
|
|
69
|
-
beforeEach(() => {
|
|
70
|
-
objectName = 'test';
|
|
71
|
-
prevObj = { hello: 'world' };
|
|
72
|
-
currObj = { hello: 'earth' };
|
|
73
|
-
changes = {
|
|
74
|
-
[objectName]: {
|
|
75
|
-
previousValue: prevObj,
|
|
76
|
-
currentValue: currObj,
|
|
77
|
-
isFirstChange: () => false,
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('if testObject has changed', () => {
|
|
83
|
-
describe('if it is not the first change', () => {
|
|
84
|
-
it('returns true if previous testObject value does not equal current testObject value -- deep check', () => {
|
|
85
|
-
const result = NgOnChangesUtilities.inputObjectChanged(
|
|
86
|
-
changes,
|
|
87
|
-
objectName
|
|
88
|
-
);
|
|
89
|
-
expect(result).toEqual(true);
|
|
90
|
-
});
|
|
91
|
-
it('returns true if previous testObject value does not equal current testObject value -- deep check, with property name', () => {
|
|
92
|
-
const result = NgOnChangesUtilities.inputObjectChanged(
|
|
93
|
-
changes,
|
|
94
|
-
objectName,
|
|
95
|
-
'hello'
|
|
96
|
-
);
|
|
97
|
-
expect(result).toEqual(true);
|
|
98
|
-
});
|
|
99
|
-
it('returns false if previous testObject equals current testObject value -- deep check', () => {
|
|
100
|
-
changes = {
|
|
101
|
-
[objectName]: new SimpleChange(prevObj, { hello: 'world' }, false),
|
|
102
|
-
};
|
|
103
|
-
const result = NgOnChangesUtilities.inputObjectChanged(
|
|
104
|
-
changes,
|
|
105
|
-
objectName
|
|
106
|
-
);
|
|
107
|
-
expect(result).toEqual(false);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('returns false if changes does not have property for input string', () => {
|
|
113
|
-
changes = { wrong: new SimpleChange('', '', false) };
|
|
114
|
-
const result = NgOnChangesUtilities.inputObjectChanged(changes, objectName);
|
|
115
|
-
expect(result).toEqual(false);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { SimpleChanges } from '@angular/core';
|
|
2
|
-
import { get, isEqual } from 'lodash-es';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* A utility class for detecting changes to objects in Angular's ngOnChanges lifecycle hook.
|
|
6
|
-
*/
|
|
7
|
-
export class NgOnChangesUtilities {
|
|
8
|
-
/**
|
|
9
|
-
* Checks if an input object has changed since the first change.
|
|
10
|
-
* @param changes - The SimpleChanges object containing the changes.
|
|
11
|
-
* @param inputName - The name of the input property to check.
|
|
12
|
-
* @param property - Optional specific property to check within the input object.
|
|
13
|
-
* @returns True if the input object has changed since the first change, otherwise false.
|
|
14
|
-
*/
|
|
15
|
-
static inputObjectChangedNotFirstTime(
|
|
16
|
-
changes: SimpleChanges,
|
|
17
|
-
inputName: string,
|
|
18
|
-
property?: string
|
|
19
|
-
): boolean {
|
|
20
|
-
return (
|
|
21
|
-
changes[inputName] !== undefined &&
|
|
22
|
-
!changes[inputName].isFirstChange() &&
|
|
23
|
-
this.inputObjectChanged(changes, inputName, property)
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Checks if an input object has changed.
|
|
29
|
-
* @param changes - The SimpleChanges object containing the changes.
|
|
30
|
-
* @param inputName - The name of the input property to check.
|
|
31
|
-
* @param property - Optional specific property to check within the input object.
|
|
32
|
-
* @returns True if the input object has changed, otherwise false.
|
|
33
|
-
*/
|
|
34
|
-
static inputObjectChanged(
|
|
35
|
-
changes: SimpleChanges,
|
|
36
|
-
inputName: string,
|
|
37
|
-
property?: string
|
|
38
|
-
): boolean {
|
|
39
|
-
let prevAccessor = `${inputName}.previousValue`;
|
|
40
|
-
let currAccessor = `${inputName}.currentValue`;
|
|
41
|
-
if (property) {
|
|
42
|
-
prevAccessor += `.${property}`;
|
|
43
|
-
currAccessor += `.${property}`;
|
|
44
|
-
}
|
|
45
|
-
return (
|
|
46
|
-
changes[inputName] !== undefined &&
|
|
47
|
-
!isEqual(get(changes, prevAccessor), get(changes, currAccessor))
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { NgZone } from '@angular/core';
|
|
2
|
-
import { Observable, switchMap } from 'rxjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* @param zone: NgZone
|
|
7
|
-
* @returns (source: Observable<T>) => Observable<void>
|
|
8
|
-
*
|
|
9
|
-
* A custom RxJS operator that runs an Angular change detection cycle after the source observable emits, and waits until the change detection cycle is complete before emitting the next value.
|
|
10
|
-
*
|
|
11
|
-
* Note that this is not intended to be used frequently. It is a workaround for cases where you need to ensure that Angular has completed change detection before continuing with the next operation, for example when you need to access a DOM element that is being created through multiple levels of content projection.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* this.myObservable.pipe(
|
|
16
|
-
* runNgChangeDetectionThen(this.zone),
|
|
17
|
-
* subscribe(() => {
|
|
18
|
-
* console.log('a change detection cycle has completed');
|
|
19
|
-
* })
|
|
20
|
-
* );
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export function runNgChangeDetectionThen<T>(
|
|
24
|
-
zone: NgZone
|
|
25
|
-
): (source: Observable<T>) => Observable<void> {
|
|
26
|
-
return function <T>(source: Observable<T>): Observable<void> {
|
|
27
|
-
return source.pipe(
|
|
28
|
-
switchMap(
|
|
29
|
-
() =>
|
|
30
|
-
new Promise<void>((resolve) => {
|
|
31
|
-
zone.run(() => {
|
|
32
|
-
Promise.resolve().then(() => {
|
|
33
|
-
resolve();
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
})
|
|
37
|
-
)
|
|
38
|
-
);
|
|
39
|
-
};
|
|
40
|
-
}
|
package/src/public-api.ts
DELETED
package/tsconfig.lib.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
-
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
-
{
|
|
4
|
-
"extends": "../../tsconfig.json",
|
|
5
|
-
"compilerOptions": {
|
|
6
|
-
"outDir": "../../out-tsc/lib",
|
|
7
|
-
"declaration": true,
|
|
8
|
-
"declarationMap": true,
|
|
9
|
-
"inlineSources": true,
|
|
10
|
-
"types": [],
|
|
11
|
-
"paths": {
|
|
12
|
-
"@mathstack/*": ["dist/*"]
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"exclude": ["**/*.spec.ts"]
|
|
16
|
-
}
|
package/tsconfig.lib.prod.json
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
-
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
-
{
|
|
4
|
-
"extends": "./tsconfig.lib.json",
|
|
5
|
-
"compilerOptions": {
|
|
6
|
-
"declarationMap": false
|
|
7
|
-
},
|
|
8
|
-
"angularCompilerOptions": {
|
|
9
|
-
"compilationMode": "partial"
|
|
10
|
-
}
|
|
11
|
-
}
|
package/tsconfig.spec.json
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
-
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
-
{
|
|
4
|
-
"extends": "../../tsconfig.json",
|
|
5
|
-
"compilerOptions": {
|
|
6
|
-
"outDir": "../../out-tsc/spec",
|
|
7
|
-
"types": ["jasmine"]
|
|
8
|
-
},
|
|
9
|
-
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
|
10
|
-
}
|