@heartlandone/vega-angular-sandbox-pr-2327-5b91658d7c54c195ad59a3ecd2b440a347320dd1 2.61.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/.browserslistrc +16 -0
- package/.prettierrc.js +13 -0
- package/LICENSE +13 -0
- package/README.md +86 -0
- package/dist/LICENSE +13 -0
- package/dist/README.md +86 -0
- package/dist/esm2020/heartlandone-vega-angular.mjs +5 -0
- package/dist/esm2020/lib/components-module.mjs +35 -0
- package/dist/esm2020/lib/stencil-generated/angular-component-lib/utils.mjs +89 -0
- package/dist/esm2020/lib/stencil-generated/components.mjs +2908 -0
- package/dist/esm2020/lib/stencil-generated/text-value-accessor.mjs +36 -0
- package/dist/esm2020/lib/stencil-generated/value-accessor.mjs +47 -0
- package/dist/esm2020/public-api.mjs +8 -0
- package/dist/esm2020/testing/heartlandone-vega-angular-testing.mjs +5 -0
- package/dist/esm2020/testing/index.mjs +84 -0
- package/dist/esm2020/testing/public-api.mjs +5 -0
- package/dist/fesm2015/heartlandone-vega-angular-testing.mjs +97 -0
- package/dist/fesm2015/heartlandone-vega-angular-testing.mjs.map +1 -0
- package/dist/fesm2015/heartlandone-vega-angular.mjs +3000 -0
- package/dist/fesm2015/heartlandone-vega-angular.mjs.map +1 -0
- package/dist/fesm2020/heartlandone-vega-angular-testing.mjs +94 -0
- package/dist/fesm2020/heartlandone-vega-angular-testing.mjs.map +1 -0
- package/dist/fesm2020/heartlandone-vega-angular.mjs +3000 -0
- package/dist/fesm2020/heartlandone-vega-angular.mjs.map +1 -0
- package/dist/heartlandone-vega-angular.d.ts +5 -0
- package/dist/lib/components-module.d.ts +11 -0
- package/dist/lib/stencil-generated/angular-component-lib/utils.d.ts +9 -0
- package/dist/lib/stencil-generated/components.d.ts +1990 -0
- package/dist/lib/stencil-generated/text-value-accessor.d.ts +8 -0
- package/dist/lib/stencil-generated/value-accessor.d.ts +18 -0
- package/dist/package.json +50 -0
- package/dist/public-api.d.ts +4 -0
- package/dist/testing/heartlandone-vega-angular-testing.d.ts +5 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/package.json +10 -0
- package/dist/testing/public-api.d.ts +1 -0
- package/karma.conf.js +44 -0
- package/ng-package.json +11 -0
- package/package.json +38 -0
- package/src/lib/components-module.ts +27 -0
- package/src/lib/stencil-generated/angular-component-lib/utils.ts +101 -0
- package/src/lib/stencil-generated/components.ts +3582 -0
- package/src/lib/stencil-generated/text-value-accessor.ts +25 -0
- package/src/lib/stencil-generated/value-accessor.ts +45 -0
- package/src/public-api.ts +7 -0
- package/src/scripts/stencil-post-build-script.js +132 -0
- package/src/test.ts +27 -0
- package/testing/index.ts +115 -0
- package/testing/ng-package.json +8 -0
- package/testing/public-api.ts +4 -0
- package/tsconfig.lib.json +15 -0
- package/tsconfig.lib.prod.json +10 -0
- package/tsconfig.spec.json +17 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
import { Directive, ElementRef } from '@angular/core';
|
2
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
3
|
+
|
4
|
+
import { ValueAccessor } from './value-accessor';
|
5
|
+
|
6
|
+
@Directive({
|
7
|
+
/* tslint:disable-next-line:directive-selector */
|
8
|
+
selector: 'vega-checkbox, vega-checkbox-group, vega-color-picker, vega-combo-box, vega-date-picker, vega-file-uploader, vega-image-uploader, vega-input, vega-input-credit-card, vega-input-numeric, vega-input-phone-number, vega-input-range, vega-input-select, vega-radio-group, vega-rich-text-editor, vega-selection-chip-group, vega-selection-tile-group, vega-signature-capture, vega-stepper, vega-textarea, vega-time-picker, vega-toggle-switch',
|
9
|
+
host: {
|
10
|
+
'(vegaChange)': "handleChangeEvent($event.currentTarget.value, 'vega')",
|
11
|
+
'(change)': "handleChangeEvent($event.currentTarget.value, 'native')"
|
12
|
+
},
|
13
|
+
providers: [
|
14
|
+
{
|
15
|
+
provide: NG_VALUE_ACCESSOR,
|
16
|
+
useExisting: TextValueAccessor,
|
17
|
+
multi: true
|
18
|
+
}
|
19
|
+
]
|
20
|
+
})
|
21
|
+
export class TextValueAccessor extends ValueAccessor {
|
22
|
+
constructor(el: ElementRef) {
|
23
|
+
super(el);
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { Directive, ElementRef, HostListener } from '@angular/core';
|
2
|
+
import { ControlValueAccessor } from '@angular/forms';
|
3
|
+
import { VegaEventManager } from '@heartlandone/vega';
|
4
|
+
|
5
|
+
@Directive({ selector: 'vega-value-accessor' })
|
6
|
+
export class ValueAccessor implements ControlValueAccessor {
|
7
|
+
private onChange: (value: any) => void = () => {
|
8
|
+
/**/
|
9
|
+
};
|
10
|
+
private onTouched: () => void = () => {
|
11
|
+
/**/
|
12
|
+
};
|
13
|
+
protected lastValue: any;
|
14
|
+
|
15
|
+
constructor(protected el: ElementRef) {}
|
16
|
+
|
17
|
+
writeValue(value: any) {
|
18
|
+
this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
|
19
|
+
}
|
20
|
+
|
21
|
+
handleChangeEvent(value: any, semantics: 'native' | 'vega') {
|
22
|
+
if(VegaEventManager.getSemantics(this.el.nativeElement).namespace === semantics){
|
23
|
+
if (value !== this.lastValue) {
|
24
|
+
this.lastValue = value;
|
25
|
+
this.onChange(value);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
@HostListener('focusout')
|
31
|
+
_handleBlurEvent() {
|
32
|
+
this.onTouched();
|
33
|
+
}
|
34
|
+
|
35
|
+
registerOnChange(fn: (value: any) => void) {
|
36
|
+
this.onChange = fn;
|
37
|
+
}
|
38
|
+
registerOnTouched(fn: () => void) {
|
39
|
+
this.onTouched = fn;
|
40
|
+
}
|
41
|
+
|
42
|
+
setDisabledState(isDisabled: boolean) {
|
43
|
+
this.el.nativeElement.disabled = isDisabled;
|
44
|
+
}
|
45
|
+
}
|
@@ -0,0 +1,132 @@
|
|
1
|
+
const { execSync } = require('child_process');
|
2
|
+
const { readFileSync, writeFileSync } = require('fs');
|
3
|
+
const STENCIL_GENERATED_COMPONENTS_PATH = 'src/lib/stencil-generated/components.ts';
|
4
|
+
const STENCIL_GENERATED_TEXT_VALUE_ACCESSOR_PATH = 'src/lib/stencil-generated/text-value-accessor.ts';
|
5
|
+
|
6
|
+
function updateStencilGenerated(filePath, updaters) {
|
7
|
+
let componentsContent = readFileSync(filePath, 'utf8');
|
8
|
+
|
9
|
+
updaters.forEach(updater => {
|
10
|
+
componentsContent = updater(componentsContent);
|
11
|
+
});
|
12
|
+
|
13
|
+
writeFileSync(filePath, componentsContent);
|
14
|
+
}
|
15
|
+
|
16
|
+
function appendDefaultArrayExportInComponentsFile(componentsContent) {
|
17
|
+
// extract the name of export vega component classes
|
18
|
+
const exportedClass = Array.from(componentsContent.matchAll(/export class (Vega[a-zA-Z]+) {/g)).map(
|
19
|
+
matched => matched[1],
|
20
|
+
);
|
21
|
+
|
22
|
+
// append default export statement to the original file
|
23
|
+
const exportDefaultStatement = `
|
24
|
+
export default [
|
25
|
+
${exportedClass.join(',\n ')},
|
26
|
+
];`;
|
27
|
+
return componentsContent + exportDefaultStatement;
|
28
|
+
}
|
29
|
+
|
30
|
+
function resolveEventPayloadImportPath(componentsContent) {
|
31
|
+
const EVENT_PAYLOAD_TYPE_TO_COMPONENT_TAG_MAP = new Map([
|
32
|
+
['VegaTableChangePropType', 'vega-table/interface'],
|
33
|
+
['VegaTableRowClickPropType', 'vega-table/interface'],
|
34
|
+
['VegaTableRowSelectProp', 'vega-table/interface'],
|
35
|
+
['VegaTableSelectAllProp', 'vega-table/interface'],
|
36
|
+
['VegaFileOptional', 'vega-image-uploader/types'],
|
37
|
+
['SelectValueType', 'vega-input-select/types'],
|
38
|
+
['SelectType', 'vega-input-select/types'],
|
39
|
+
['VegaBreadcrumbItemType', 'vega-breadcrumb/types'],
|
40
|
+
['VegaTableHeadCellClickEvent', 'vega-table/interface'],
|
41
|
+
['VegaTableRowClickEvent', 'vega-table/interface'],
|
42
|
+
['VegaTableRowExpandEvent', 'vega-table/interface'],
|
43
|
+
['VegaDropdownItemClickEvent', 'vega-dropdown/vega-dropdown-item/types'],
|
44
|
+
['VegaCalendarChangeEventType', 'vega-calendar/types'],
|
45
|
+
['VegaCalendarEventClickInfo', 'vega-calendar/types'],
|
46
|
+
['VegaCalendarDateClickInfo', 'vega-calendar/types'],
|
47
|
+
['VegaCountryType', 'vega-input-phone-number/types'],
|
48
|
+
['VegaBannerActionButtonType', 'vega-banner/types'],
|
49
|
+
['VegaSignatureValue', 'vega-signature-capture/types'],
|
50
|
+
['VegaTableRowSelectEventDetail', 'vega-table/interface'],
|
51
|
+
['VegaTableRowSelectAllEventDetail', 'vega-table/interface'],
|
52
|
+
['VegaTableRowExpandEventDetail', 'vega-table/interface'],
|
53
|
+
['VegaFileUploaderFiles', 'vega-file-uploader/types'],
|
54
|
+
['VegaFileUploaderFile', 'vega-file-uploader/types'],
|
55
|
+
['VegaDropdownSearchTriggerEventDetail', 'vega-dropdown/types'],
|
56
|
+
['VegaRTEContentBlock', 'vega-rich-text-editor/interface'],
|
57
|
+
['VegaRichTextLinkEditorChangeDetail', 'vega-rich-text-editor/vega-rich-text-link-editor/types'],
|
58
|
+
['VegaRichTextImageEditorChangeDetail', 'vega-rich-text-editor/vega-rich-text-image-editor/types'],
|
59
|
+
['VegaRichTextEditorImage', 'vega-rich-text-editor/interface'],
|
60
|
+
['VegaRTEContent', 'vega-rich-text-editor/dto/content-state'],
|
61
|
+
['VegaCodeBlockValue', 'vega-code-block/types'],
|
62
|
+
['DatePickerMonthYearTypes', 'vega-date-picker/types']
|
63
|
+
]);
|
64
|
+
|
65
|
+
return componentsContent.replace(
|
66
|
+
/(import type { (.*) as .* } from )'@heartlandone\/vega'/g,
|
67
|
+
function (matched, group1, group2) {
|
68
|
+
const componentTypePath = EVENT_PAYLOAD_TYPE_TO_COMPONENT_TAG_MAP.get(group2);
|
69
|
+
return `${group1}'@heartlandone/vega/dist/types/components/${componentTypePath}'`;
|
70
|
+
},
|
71
|
+
);
|
72
|
+
}
|
73
|
+
|
74
|
+
function extraReplaces(componentsContent) {
|
75
|
+
const replaces = [
|
76
|
+
[
|
77
|
+
'<SelectValueType<IVegaInputSelectSelectType>>',
|
78
|
+
'<IVegaInputSelectSelectValueType<IVegaInputSelectSelectType>>',
|
79
|
+
],
|
80
|
+
];
|
81
|
+
replaces.forEach(item => {
|
82
|
+
componentsContent = componentsContent.replace(new RegExp(item[0], 'g'), item[1]);
|
83
|
+
});
|
84
|
+
return componentsContent;
|
85
|
+
}
|
86
|
+
|
87
|
+
function revertValueAccessorChangeByGit() {
|
88
|
+
// use git to reset the change in value-accessor made by stencil angular output,
|
89
|
+
// since it will make the directive annotation without any property which will causing compile error
|
90
|
+
execSync('git checkout -- src/lib/stencil-generated/value-accessor.ts');
|
91
|
+
}
|
92
|
+
|
93
|
+
function revertUtilsChange() {
|
94
|
+
execSync('git checkout -- src/lib/stencil-generated/angular-component-lib/utils.ts');
|
95
|
+
}
|
96
|
+
|
97
|
+
function addSemanticsParamToHandleChangeEvent(content) {
|
98
|
+
const replaces = [
|
99
|
+
[
|
100
|
+
`'(vegaChange)': 'handleChangeEvent($event.target.value)'`,
|
101
|
+
`'(vegaChange)': "handleChangeEvent($event.currentTarget.value, 'vega')"`,
|
102
|
+
],
|
103
|
+
[
|
104
|
+
`'(change)': 'handleChangeEvent($event.target.value)'`,
|
105
|
+
`'(change)': "handleChangeEvent($event.currentTarget.value, 'native')"`,
|
106
|
+
],
|
107
|
+
];
|
108
|
+
replaces.forEach(item => {
|
109
|
+
content = content.replace(item[0], item[1]);
|
110
|
+
});
|
111
|
+
return content;
|
112
|
+
}
|
113
|
+
|
114
|
+
updateStencilGenerated(
|
115
|
+
STENCIL_GENERATED_COMPONENTS_PATH,
|
116
|
+
[
|
117
|
+
appendDefaultArrayExportInComponentsFile,
|
118
|
+
resolveEventPayloadImportPath,
|
119
|
+
extraReplaces,
|
120
|
+
]
|
121
|
+
);
|
122
|
+
|
123
|
+
updateStencilGenerated(
|
124
|
+
STENCIL_GENERATED_TEXT_VALUE_ACCESSOR_PATH,
|
125
|
+
[
|
126
|
+
addSemanticsParamToHandleChangeEvent
|
127
|
+
]
|
128
|
+
);
|
129
|
+
|
130
|
+
revertValueAccessorChangeByGit();
|
131
|
+
|
132
|
+
revertUtilsChange();
|
package/src/test.ts
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
2
|
+
|
3
|
+
import 'zone.js';
|
4
|
+
import 'zone.js/testing';
|
5
|
+
import { getTestBed } from '@angular/core/testing';
|
6
|
+
import {
|
7
|
+
BrowserDynamicTestingModule,
|
8
|
+
platformBrowserDynamicTesting
|
9
|
+
} from '@angular/platform-browser-dynamic/testing';
|
10
|
+
|
11
|
+
declare const require: {
|
12
|
+
context(path: string, deep?: boolean, filter?: RegExp): {
|
13
|
+
<T>(id: string): T;
|
14
|
+
keys(): string[];
|
15
|
+
};
|
16
|
+
};
|
17
|
+
|
18
|
+
// First, initialize the Angular testing environment.
|
19
|
+
getTestBed().initTestEnvironment(
|
20
|
+
BrowserDynamicTestingModule,
|
21
|
+
platformBrowserDynamicTesting(),
|
22
|
+
);
|
23
|
+
|
24
|
+
// Then we find all the tests.
|
25
|
+
const context = require.context('./', true, /\.spec\.ts$/);
|
26
|
+
// And load the modules.
|
27
|
+
context.keys().map(context);
|
package/testing/index.ts
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
import { FeatureFlag } from '@heartlandone/vega';
|
2
|
+
import { waitForVega } from '@heartlandone/vega';
|
3
|
+
import type { RenderResult } from '@testing-library/angular';
|
4
|
+
|
5
|
+
type Nullable<T> = T | undefined | null;
|
6
|
+
|
7
|
+
export async function waitForVegaReady(
|
8
|
+
renderResult: RenderResult<unknown, unknown>,
|
9
|
+
delay: number = 300,
|
10
|
+
): Promise<RenderResult<unknown, unknown>> {
|
11
|
+
await waitForVega();
|
12
|
+
|
13
|
+
/*
|
14
|
+
* The following code is added to load the vega component, and the attribute value is set after each component is loaded.
|
15
|
+
* To determine whether there is a hydrated style that cannot meet the requirements after the component is loaded,
|
16
|
+
* It need to set the sleep time to ensure that each attribute of the vega component is fully loaded
|
17
|
+
*
|
18
|
+
code link: ./node_modules/@heartlandone/vega-react/dist/react-component-lib/utils/attachProps.js(line 28-33)}
|
19
|
+
*/
|
20
|
+
await sleep(delay);
|
21
|
+
return renderResult;
|
22
|
+
}
|
23
|
+
|
24
|
+
export type MockedResizeObserverController = {
|
25
|
+
hide: (selector: string, container?: HTMLElement) => void;
|
26
|
+
show: (selector: string, container?: HTMLElement) => void;
|
27
|
+
};
|
28
|
+
|
29
|
+
export function mockResizeObserver(): MockedResizeObserverController {
|
30
|
+
type MockedResizeObserver = ResizeObserver & {
|
31
|
+
show: () => void;
|
32
|
+
hide: () => void;
|
33
|
+
};
|
34
|
+
FeatureFlag.disable('VEGA_ANGULAR.USE_JUGGLE_RESIZE_OBSERVER');
|
35
|
+
const resizeObserverElementMap: Map<HTMLElement, MockedResizeObserver> = new Map();
|
36
|
+
const VegaResizeObserver: unknown = class {
|
37
|
+
private readonly callback: ResizeObserverCallback;
|
38
|
+
private observedElements: HTMLElement[] = [];
|
39
|
+
constructor(callback: ResizeObserverCallback) {
|
40
|
+
this.callback = callback;
|
41
|
+
}
|
42
|
+
|
43
|
+
observe(element: HTMLElement): void {
|
44
|
+
if (!this.isObserved(element)) {
|
45
|
+
resizeObserverElementMap.set(element, this);
|
46
|
+
this.observedElements.push(element);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
unobserve(element: HTMLElement): void {
|
51
|
+
if (this.isObserved(element)) {
|
52
|
+
resizeObserverElementMap.delete(element);
|
53
|
+
this.observedElements = this.observedElements.filter(
|
54
|
+
(observedElement: HTMLElement) => observedElement !== element,
|
55
|
+
);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
disconnect(): void {
|
60
|
+
for (const element of this.observedElements) {
|
61
|
+
resizeObserverElementMap.delete(element);
|
62
|
+
}
|
63
|
+
this.observedElements = [];
|
64
|
+
}
|
65
|
+
|
66
|
+
show(): void {
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
68
|
+
this.callback([{ contentRect: { height: 100 } }] as any, this);
|
69
|
+
}
|
70
|
+
|
71
|
+
hide(): void {
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
73
|
+
this.callback([{ contentRect: { height: 0 } }] as any, this);
|
74
|
+
}
|
75
|
+
|
76
|
+
private isObserved(element: HTMLElement): boolean {
|
77
|
+
return this.observedElements.includes(element);
|
78
|
+
}
|
79
|
+
};
|
80
|
+
Object.assign(window, { VegaResizeObserver });
|
81
|
+
return {
|
82
|
+
show: (selector: string, container?: HTMLElement): void => {
|
83
|
+
(container || document)
|
84
|
+
.querySelectorAll(selector)
|
85
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
86
|
+
.forEach((el: Element) => {
|
87
|
+
const resizeObserver: Nullable<MockedResizeObserver> = resizeObserverElementMap.get(
|
88
|
+
el as HTMLElement,
|
89
|
+
);
|
90
|
+
if (resizeObserver) {
|
91
|
+
resizeObserver.show();
|
92
|
+
}
|
93
|
+
});
|
94
|
+
},
|
95
|
+
hide: (selector: string, container?: HTMLElement): void => {
|
96
|
+
(container || document)
|
97
|
+
.querySelectorAll(selector)
|
98
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
99
|
+
.forEach((el: Element) => {
|
100
|
+
const resizeObserver: Nullable<MockedResizeObserver> = resizeObserverElementMap.get(
|
101
|
+
el as HTMLElement,
|
102
|
+
);
|
103
|
+
if (resizeObserver) {
|
104
|
+
resizeObserver.hide();
|
105
|
+
}
|
106
|
+
});
|
107
|
+
},
|
108
|
+
};
|
109
|
+
}
|
110
|
+
|
111
|
+
function sleep(ms: number): Promise<void> {
|
112
|
+
return new Promise((resolve: () => void) => {
|
113
|
+
setTimeout(resolve, ms);
|
114
|
+
});
|
115
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
2
|
+
{
|
3
|
+
"extends": "../../tsconfig.json",
|
4
|
+
"compilerOptions": {
|
5
|
+
"outDir": "../../out-tsc/lib",
|
6
|
+
"declaration": true,
|
7
|
+
"declarationMap": true,
|
8
|
+
"inlineSources": true,
|
9
|
+
"types": []
|
10
|
+
},
|
11
|
+
"exclude": [
|
12
|
+
"src/test.ts",
|
13
|
+
"**/*.spec.ts"
|
14
|
+
]
|
15
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
2
|
+
{
|
3
|
+
"extends": "../../tsconfig.json",
|
4
|
+
"compilerOptions": {
|
5
|
+
"outDir": "../../out-tsc/spec",
|
6
|
+
"types": [
|
7
|
+
"jasmine"
|
8
|
+
]
|
9
|
+
},
|
10
|
+
"files": [
|
11
|
+
"src/test.ts"
|
12
|
+
],
|
13
|
+
"include": [
|
14
|
+
"**/*.spec.ts",
|
15
|
+
"**/*.d.ts"
|
16
|
+
]
|
17
|
+
}
|