@stencil/angular-output-target 0.6.1-dev.11655499531.137e1d26 → 0.6.1-dev.11662577182.1c45c8de
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/README.md +2 -2
- package/angular-component-lib/utils.ts +8 -31
- package/dist/generate-angular-component.d.ts +22 -2
- package/dist/generate-angular-component.js +117 -107
- package/dist/generate-angular-directives-file.js +1 -1
- package/dist/generate-angular-modules.d.ts +6 -0
- package/dist/generate-angular-modules.js +17 -0
- package/dist/generate-value-accessors.js +3 -6
- package/dist/index.cjs.js +266 -163
- package/dist/index.js +266 -163
- package/dist/output-angular.js +82 -40
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js +8 -5
- package/dist/types.d.ts +18 -2
- package/dist/utils.d.ts +24 -6
- package/dist/utils.js +42 -7
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ export const config: Config = {
|
|
|
27
27
|
outputTargets: [
|
|
28
28
|
angularOutputTarget({
|
|
29
29
|
componentCorePackage: 'component-library',
|
|
30
|
-
|
|
30
|
+
proxyDeclarationFile: '../component-library-angular/src/directives/proxies.ts',
|
|
31
31
|
directivesArrayFile: '../component-library-angular/src/directives/index.ts',
|
|
32
32
|
}),
|
|
33
33
|
{
|
|
@@ -43,7 +43,7 @@ export const config: Config = {
|
|
|
43
43
|
| Property | Description |
|
|
44
44
|
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
45
|
| `componentCorePackage` | The NPM package name of your Stencil component library. This package is used as a dependency for your Angular wrappers. |
|
|
46
|
-
| `
|
|
46
|
+
| `proxyDeclarationFile` | The output file of all the component wrappers generated by the output target. This file path should point to a location within your Angular library/project. |
|
|
47
47
|
| `directivesArrayFile` | The output file of a constant of all the generated component wrapper classes. Used for easily declaring and exporting the generated components from an `NgModule`. This file path should point to a location within your Angular library/project. |
|
|
48
48
|
| `valueAccessorConfigs` | The configuration object for how individual web components behave with Angular control value accessors. |
|
|
49
49
|
| `excludeComponents` | An array of tag names to exclude from generating component wrappers for. This is helpful when have a custom framework implementation of a specific component or need to extend the base component wrapper behavior. |
|
|
@@ -4,61 +4,40 @@ import { fromEvent } from 'rxjs';
|
|
|
4
4
|
|
|
5
5
|
export const proxyInputs = (Cmp: any, inputs: string[]) => {
|
|
6
6
|
const Prototype = Cmp.prototype;
|
|
7
|
-
|
|
8
|
-
inputs.forEach(item => {
|
|
7
|
+
inputs.forEach((item) => {
|
|
9
8
|
Object.defineProperty(Prototype, item, {
|
|
10
9
|
get() {
|
|
11
10
|
return this.el[item];
|
|
12
11
|
},
|
|
13
12
|
set(val: any) {
|
|
14
13
|
this.z.runOutsideAngular(() => (this.el[item] = val));
|
|
15
|
-
}
|
|
14
|
+
},
|
|
16
15
|
});
|
|
17
16
|
});
|
|
18
17
|
};
|
|
19
18
|
|
|
20
19
|
export const proxyMethods = (Cmp: any, methods: string[]) => {
|
|
21
20
|
const Prototype = Cmp.prototype;
|
|
22
|
-
methods.forEach(methodName => {
|
|
21
|
+
methods.forEach((methodName) => {
|
|
23
22
|
Prototype[methodName] = function () {
|
|
24
23
|
const args = arguments;
|
|
25
|
-
return this.z.runOutsideAngular(() =>
|
|
26
|
-
this.el[methodName].apply(this.el, args)
|
|
27
|
-
);
|
|
24
|
+
return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args));
|
|
28
25
|
};
|
|
29
26
|
});
|
|
30
27
|
};
|
|
31
28
|
|
|
32
29
|
export const proxyOutputs = (instance: any, el: any, events: string[]) => {
|
|
33
|
-
events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
|
|
34
|
-
}
|
|
30
|
+
events.forEach((eventName) => (instance[eventName] = fromEvent(el, eventName)));
|
|
31
|
+
};
|
|
35
32
|
|
|
36
33
|
export const defineCustomElement = (tagName: string, customElement: any) => {
|
|
37
|
-
if (
|
|
38
|
-
customElement !== undefined &&
|
|
39
|
-
typeof customElements !== 'undefined' &&
|
|
40
|
-
!customElements.get(tagName)
|
|
41
|
-
) {
|
|
34
|
+
if (customElement !== undefined && typeof customElements !== 'undefined' && !customElements.get(tagName)) {
|
|
42
35
|
customElements.define(tagName, customElement);
|
|
43
36
|
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const NG_COMP_DEF = 'ɵcmp';
|
|
47
|
-
|
|
48
|
-
export const clearAngularOutputBindings = (cls: any) => {
|
|
49
|
-
const instance = cls.prototype.constructor;
|
|
50
|
-
if (instance[NG_COMP_DEF]) {
|
|
51
|
-
/**
|
|
52
|
-
* With the output targets generating @Output() proxies, we need to
|
|
53
|
-
* clear the metadata (ɵcmp.outputs) so that Angular does not add its own event listener
|
|
54
|
-
* and cause duplicate event emissions for the web component events.
|
|
55
|
-
*/
|
|
56
|
-
instance[NG_COMP_DEF].outputs = {};
|
|
57
|
-
}
|
|
58
37
|
};
|
|
59
38
|
|
|
60
39
|
// tslint:disable-next-line: only-arrow-functions
|
|
61
|
-
export function ProxyCmp(opts: { defineCustomElementFn?: () => void
|
|
40
|
+
export function ProxyCmp(opts: { defineCustomElementFn?: () => void; inputs?: any; methods?: any }) {
|
|
62
41
|
const decorator = function (cls: any) {
|
|
63
42
|
const { defineCustomElementFn, inputs, methods } = opts;
|
|
64
43
|
|
|
@@ -66,8 +45,6 @@ export function ProxyCmp(opts: { defineCustomElementFn?: () => void, inputs?: an
|
|
|
66
45
|
defineCustomElementFn();
|
|
67
46
|
}
|
|
68
47
|
|
|
69
|
-
clearAngularOutputBindings(cls);
|
|
70
|
-
|
|
71
48
|
if (inputs) {
|
|
72
49
|
proxyInputs(cls, inputs);
|
|
73
50
|
}
|
|
@@ -1,2 +1,22 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { ComponentCompilerEvent } from '@stencil/core/internal';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an Angular component declaration from formatted Stencil compiler metadata.
|
|
4
|
+
*
|
|
5
|
+
* @param tagName The tag name of the component.
|
|
6
|
+
* @param inputs The inputs of the Stencil component (e.g. ['myInput']).
|
|
7
|
+
* @param outputs The outputs/events of the Stencil component. (e.g. ['myOutput']).
|
|
8
|
+
* @param methods The methods of the Stencil component. (e.g. ['myMethod']).
|
|
9
|
+
* @param includeImportCustomElements Whether to define the component as a custom element.
|
|
10
|
+
* @returns The component declaration as a string.
|
|
11
|
+
*/
|
|
12
|
+
export declare const createAngularComponentDefinition: (tagName: string, inputs: readonly string[], outputs: readonly string[], methods: readonly string[], includeImportCustomElements?: boolean) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Creates the component interface type definition.
|
|
15
|
+
* @param tagNameAsPascal The tag name as PascalCase.
|
|
16
|
+
* @param events The events to generate the interface properties for.
|
|
17
|
+
* @param componentCorePackage The component core package.
|
|
18
|
+
* @param includeImportCustomElements Whether to include the import for the custom element definition.
|
|
19
|
+
* @param customElementsDir The custom elements directory.
|
|
20
|
+
* @returns The component interface type definition as a string.
|
|
21
|
+
*/
|
|
22
|
+
export declare const createComponentTypeDefinition: (tagNameAsPascal: string, events: readonly ComponentCompilerEvent[], componentCorePackage: string, includeImportCustomElements?: boolean, customElementsDir?: string | undefined) => string;
|
|
@@ -1,116 +1,126 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { createComponentEventTypeImports, dashToPascalCase, formatToQuotedList } from './utils';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an Angular component declaration from formatted Stencil compiler metadata.
|
|
4
|
+
*
|
|
5
|
+
* @param tagName The tag name of the component.
|
|
6
|
+
* @param inputs The inputs of the Stencil component (e.g. ['myInput']).
|
|
7
|
+
* @param outputs The outputs/events of the Stencil component. (e.g. ['myOutput']).
|
|
8
|
+
* @param methods The methods of the Stencil component. (e.g. ['myMethod']).
|
|
9
|
+
* @param includeImportCustomElements Whether to define the component as a custom element.
|
|
10
|
+
* @returns The component declaration as a string.
|
|
11
|
+
*/
|
|
12
|
+
export const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false) => {
|
|
13
|
+
const tagNameAsPascal = dashToPascalCase(tagName);
|
|
14
|
+
const hasInputs = inputs.length > 0;
|
|
11
15
|
const hasOutputs = outputs.length > 0;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const hasMethods = methods.length > 0;
|
|
17
|
+
// Formats the input strings into comma separated, single quoted values.
|
|
18
|
+
const formattedInputs = formatToQuotedList(inputs);
|
|
19
|
+
// Formats the output strings into comma separated, single quoted values.
|
|
20
|
+
const formattedOutputs = formatToQuotedList(outputs);
|
|
21
|
+
// Formats the method strings into comma separated, single quoted values.
|
|
22
|
+
const formattedMethods = formatToQuotedList(methods);
|
|
23
|
+
const proxyCmpOptions = [];
|
|
24
|
+
if (includeImportCustomElements) {
|
|
25
|
+
const defineCustomElementFn = `define${tagNameAsPascal}`;
|
|
26
|
+
proxyCmpOptions.push(`\n defineCustomElementFn: ${defineCustomElementFn}`);
|
|
27
|
+
}
|
|
28
|
+
if (hasInputs) {
|
|
29
|
+
proxyCmpOptions.push(`\n inputs: [${formattedInputs}]`);
|
|
30
|
+
}
|
|
31
|
+
if (hasMethods) {
|
|
32
|
+
proxyCmpOptions.push(`\n methods: [${formattedMethods}]`);
|
|
20
33
|
}
|
|
21
|
-
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
22
|
-
const outputsInterface = new Set();
|
|
23
|
-
const outputReferenceRemap = {};
|
|
24
|
-
outputs.forEach((output) => {
|
|
25
|
-
Object.entries(output.complexType.references).forEach(([reference, refObject]) => {
|
|
26
|
-
// Add import line for each local/import reference, and add new mapping name.
|
|
27
|
-
// `outputReferenceRemap` should be updated only if the import interface is set in outputsInterface,
|
|
28
|
-
// this will prevent global types to be remapped.
|
|
29
|
-
const remappedReference = `I${cmpMeta.componentClassName}${reference}`;
|
|
30
|
-
if (refObject.location === 'local' || refObject.location === 'import') {
|
|
31
|
-
outputReferenceRemap[reference] = remappedReference;
|
|
32
|
-
let importLocation = componentCorePackage;
|
|
33
|
-
if (componentCorePackage !== undefined) {
|
|
34
|
-
const dirPath = includeImportCustomElements ? `/${customElementsDir || 'components'}` : '';
|
|
35
|
-
importLocation = `${normalizePath(componentCorePackage)}${dirPath}`;
|
|
36
|
-
}
|
|
37
|
-
outputsInterface.add(`import type { ${reference} as ${remappedReference} } from '${importLocation}';`);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
const componentEvents = [
|
|
42
|
-
'' // Empty first line
|
|
43
|
-
];
|
|
44
34
|
/**
|
|
45
|
-
*
|
|
35
|
+
* Notes on the generated output:
|
|
36
|
+
* - We disable @angular-eslint/no-inputs-metadata-property, so that
|
|
37
|
+
* Angular does not complain about the inputs property. The output target
|
|
38
|
+
* uses the inputs property to define the inputs of the component instead of
|
|
39
|
+
* having to use the @Input decorator (and manually define the type and default value).
|
|
46
40
|
*/
|
|
47
|
-
const
|
|
48
|
-
''
|
|
49
|
-
];
|
|
50
|
-
// Generate outputs
|
|
51
|
-
outputs.forEach((output, index) => {
|
|
52
|
-
componentEvents.push(` /**
|
|
53
|
-
* ${output.docs.text} ${output.docs.tags.map((tag) => `@${tag.name} ${tag.text}`)}
|
|
54
|
-
*/`);
|
|
55
|
-
/**
|
|
56
|
-
* The original attribute contains the original type defined by the devs.
|
|
57
|
-
* This regexp normalizes the reference, by removing linebreaks,
|
|
58
|
-
* replacing consecutive spaces with a single space, and adding a single space after commas.
|
|
59
|
-
**/
|
|
60
|
-
const outputTypeRemapped = Object.entries(outputReferenceRemap).reduce((type, [src, dst]) => {
|
|
61
|
-
return type
|
|
62
|
-
.replace(new RegExp(`^${src}$`, 'g'), `${dst}`)
|
|
63
|
-
.replace(new RegExp(`([^\\w])${src}([^\\w])`, 'g'), (v, p1, p2) => [p1, dst, p2].join(''));
|
|
64
|
-
}, output.complexType.original
|
|
65
|
-
.replace(/\n/g, ' ')
|
|
66
|
-
.replace(/\s{2,}/g, ' ')
|
|
67
|
-
.replace(/,\s*/g, ', '));
|
|
68
|
-
/**
|
|
69
|
-
* Starting in Stencil 2.16.0, the compiler will generate a CustomEvent interface
|
|
70
|
-
* for each component with custom events.
|
|
71
|
-
*
|
|
72
|
-
* The name of this custom event is "ComponentTagNameCustomEvent".
|
|
73
|
-
*/
|
|
74
|
-
componentEvents.push(` ${output.name}: EventEmitter<${formatCustomEventInterfaceName(cmpMeta.tagName)}<${outputTypeRemapped.trim()}>>;`);
|
|
75
|
-
outputBindings.push(` @Output() ${output.name} = new EventEmitter<${formatCustomEventInterfaceName(cmpMeta.tagName)}<${outputTypeRemapped.trim()}>>();`);
|
|
76
|
-
if (index === outputs.length - 1) {
|
|
77
|
-
// Empty line to push end `}` to new line
|
|
78
|
-
componentEvents.push('\n');
|
|
79
|
-
outputBindings.push('\n');
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
const lines = [
|
|
83
|
-
'',
|
|
84
|
-
`${[...outputsInterface].join('\n')}
|
|
85
|
-
export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {${componentEvents.length > 1 ? componentEvents.join('\n') : ''}}
|
|
86
|
-
|
|
87
|
-
${getProxyCmp(cmpMeta.tagName, includeImportCustomElements, inputs, methods)}
|
|
41
|
+
const output = `@ProxyCmp({${proxyCmpOptions.join(',')}\n})
|
|
88
42
|
@Component({
|
|
89
|
-
${
|
|
43
|
+
selector: '${tagName}',
|
|
44
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
45
|
+
template: '<ng-content></ng-content>',
|
|
46
|
+
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
|
47
|
+
inputs: [${formattedInputs}],
|
|
90
48
|
})
|
|
91
|
-
export class ${tagNameAsPascal} {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
lines.push(' protected el: HTMLElement;');
|
|
95
|
-
lines.push(` constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
49
|
+
export class ${tagNameAsPascal} {
|
|
50
|
+
protected el: HTMLElement;
|
|
51
|
+
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
96
52
|
c.detach();
|
|
97
|
-
this.el = r.nativeElement
|
|
98
|
-
|
|
99
|
-
|
|
53
|
+
this.el = r.nativeElement;${hasOutputs
|
|
54
|
+
? `
|
|
55
|
+
proxyOutputs(this, this.el, [${formattedOutputs}]);`
|
|
56
|
+
: ''}
|
|
57
|
+
}
|
|
58
|
+
}`;
|
|
59
|
+
return output;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Sanitizes and formats the component event type.
|
|
63
|
+
* @param componentClassName The class name of the component (e.g. 'MyComponent')
|
|
64
|
+
* @param event The Stencil component event.
|
|
65
|
+
* @returns The sanitized event type as a string.
|
|
66
|
+
*/
|
|
67
|
+
const formatOutputType = (componentClassName, event) => {
|
|
68
|
+
/**
|
|
69
|
+
* The original attribute contains the original type defined by the devs.
|
|
70
|
+
* This regexp normalizes the reference, by removing linebreaks,
|
|
71
|
+
* replacing consecutive spaces with a single space, and adding a single space after commas.
|
|
72
|
+
*/
|
|
73
|
+
return Object.entries(event.complexType.references)
|
|
74
|
+
.filter(([_, refObject]) => refObject.location === 'local' || refObject.location === 'import')
|
|
75
|
+
.reduce((type, [src, dst]) => {
|
|
76
|
+
const renamedType = `I${componentClassName}${type}`;
|
|
77
|
+
return renamedType
|
|
78
|
+
.replace(new RegExp(`^${src}$`, 'g'), `${dst}`)
|
|
79
|
+
.replace(new RegExp(`([^\\w])${src}([^\\w])`, 'g'), (v, p1, p2) => [p1, dst, p2].join(''));
|
|
80
|
+
}, event.complexType.original
|
|
81
|
+
.replace(/\n/g, ' ')
|
|
82
|
+
.replace(/\s{2,}/g, ' ')
|
|
83
|
+
.replace(/,\s*/g, ', '));
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Creates a formatted comment block based on the JS doc comment.
|
|
87
|
+
* @param doc The compiler jsdoc.
|
|
88
|
+
* @returns The formatted comment block as a string.
|
|
89
|
+
*/
|
|
90
|
+
const createDocComment = (doc) => {
|
|
91
|
+
if (doc.text.trim().length === 0 && doc.tags.length === 0) {
|
|
92
|
+
return '';
|
|
100
93
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
94
|
+
return `/**
|
|
95
|
+
* ${doc.text}${doc.tags.length > 0 ? ' ' : ''}${doc.tags.map((tag) => `@${tag.name} ${tag.text}`)}
|
|
96
|
+
*/`;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Creates the component interface type definition.
|
|
100
|
+
* @param tagNameAsPascal The tag name as PascalCase.
|
|
101
|
+
* @param events The events to generate the interface properties for.
|
|
102
|
+
* @param componentCorePackage The component core package.
|
|
103
|
+
* @param includeImportCustomElements Whether to include the import for the custom element definition.
|
|
104
|
+
* @param customElementsDir The custom elements directory.
|
|
105
|
+
* @returns The component interface type definition as a string.
|
|
106
|
+
*/
|
|
107
|
+
export const createComponentTypeDefinition = (tagNameAsPascal, events, componentCorePackage, includeImportCustomElements = false, customElementsDir) => {
|
|
108
|
+
const publicEvents = events.filter(ev => !ev.internal);
|
|
109
|
+
const eventTypeImports = createComponentEventTypeImports(tagNameAsPascal, publicEvents, {
|
|
110
|
+
componentCorePackage,
|
|
111
|
+
includeImportCustomElements,
|
|
112
|
+
customElementsDir,
|
|
113
|
+
});
|
|
114
|
+
const eventTypes = publicEvents
|
|
115
|
+
.map((event) => {
|
|
116
|
+
const comment = createDocComment(event.docs);
|
|
117
|
+
return `${comment.length > 0 ? ` ${comment}` : ''}
|
|
118
|
+
${event.name}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`;
|
|
119
|
+
});
|
|
120
|
+
const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`;
|
|
121
|
+
const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '')
|
|
122
|
+
+ `${interfaceDeclaration}${eventTypes.length === 0 ? '}' : `
|
|
123
|
+
${eventTypes.join('\n')}
|
|
124
|
+
}`}`;
|
|
125
|
+
return typeDefinition;
|
|
104
126
|
};
|
|
105
|
-
function getProxyCmp(tagName, includeCustomElement, inputs, methods) {
|
|
106
|
-
const hasInputs = inputs.length > 0;
|
|
107
|
-
const hasMethods = methods.length > 0;
|
|
108
|
-
const proxMeta = [
|
|
109
|
-
`defineCustomElementFn: ${includeCustomElement ? 'define' + dashToPascalCase(tagName) : 'undefined'}`
|
|
110
|
-
];
|
|
111
|
-
if (hasInputs)
|
|
112
|
-
proxMeta.push(`inputs: ['${inputs.join(`', '`)}']`);
|
|
113
|
-
if (hasMethods)
|
|
114
|
-
proxMeta.push(`methods: ['${methods.join(`', '`)}']`);
|
|
115
|
-
return `@ProxyCmp({\n ${proxMeta.join(',\n ')}\n})`;
|
|
116
|
-
}
|
|
@@ -4,7 +4,7 @@ export function generateAngularDirectivesFile(compilerCtx, components, outputTar
|
|
|
4
4
|
if (!outputTarget.directivesArrayFile) {
|
|
5
5
|
return Promise.resolve();
|
|
6
6
|
}
|
|
7
|
-
const proxyPath = relativeImport(outputTarget.directivesArrayFile, outputTarget.
|
|
7
|
+
const proxyPath = relativeImport(outputTarget.directivesArrayFile, outputTarget.proxyDeclarationFile, '.ts');
|
|
8
8
|
const directives = components
|
|
9
9
|
.map((cmpMeta) => dashToPascalCase(cmpMeta.tagName))
|
|
10
10
|
.map((className) => `d.${className}`)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates an Angular module declaration for a component wrapper.
|
|
3
|
+
* @param componentTagName The tag name of the Stencil component.
|
|
4
|
+
* @returns The Angular module declaration as a string.
|
|
5
|
+
*/
|
|
6
|
+
export declare const generateAngularModuleForComponent: (componentTagName: string) => string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { dashToPascalCase } from './utils';
|
|
2
|
+
/**
|
|
3
|
+
* Creates an Angular module declaration for a component wrapper.
|
|
4
|
+
* @param componentTagName The tag name of the Stencil component.
|
|
5
|
+
* @returns The Angular module declaration as a string.
|
|
6
|
+
*/
|
|
7
|
+
export const generateAngularModuleForComponent = (componentTagName) => {
|
|
8
|
+
const tagNameAsPascal = dashToPascalCase(componentTagName);
|
|
9
|
+
const componentClassName = `${tagNameAsPascal}`;
|
|
10
|
+
const moduleClassName = `${tagNameAsPascal}Module`;
|
|
11
|
+
const moduleDefinition = `@NgModule({
|
|
12
|
+
declarations: [${componentClassName}],
|
|
13
|
+
exports: [${componentClassName}]
|
|
14
|
+
})
|
|
15
|
+
export class ${moduleClassName} { }`;
|
|
16
|
+
return moduleDefinition;
|
|
17
|
+
};
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { EOL } from 'os';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
export default async function generateValueAccessors(compilerCtx, components, outputTarget, config) {
|
|
4
|
-
if (!Array.isArray(outputTarget.valueAccessorConfigs) ||
|
|
5
|
-
outputTarget.valueAccessorConfigs.length === 0) {
|
|
4
|
+
if (!Array.isArray(outputTarget.valueAccessorConfigs) || outputTarget.valueAccessorConfigs.length === 0) {
|
|
6
5
|
return;
|
|
7
6
|
}
|
|
8
|
-
const targetDir = path.dirname(outputTarget.
|
|
7
|
+
const targetDir = path.dirname(outputTarget.proxyDeclarationFile);
|
|
9
8
|
const normalizedValueAccessors = outputTarget.valueAccessorConfigs.reduce((allAccessors, va) => {
|
|
10
|
-
const elementSelectors = Array.isArray(va.elementSelectors)
|
|
11
|
-
? va.elementSelectors
|
|
12
|
-
: [va.elementSelectors];
|
|
9
|
+
const elementSelectors = Array.isArray(va.elementSelectors) ? va.elementSelectors : [va.elementSelectors];
|
|
13
10
|
const type = va.type;
|
|
14
11
|
let allElementSelectors = [];
|
|
15
12
|
let allEventTargets = [];
|