@stencil/angular-output-target 0.9.0 → 0.10.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/README.md +1 -0
- package/dist/generate-angular-component.d.ts +3 -2
- package/dist/generate-angular-component.js +24 -13
- package/dist/generate-value-accessors.js +1 -0
- package/dist/index.cjs.js +31 -16
- package/dist/index.js +31 -16
- package/dist/output-angular.js +6 -3
- package/dist/types.d.ts +6 -0
- package/package.json +5 -1
- package/resources/control-value-accessors/boolean-value-accessor.ts +1 -1
- package/resources/control-value-accessors/number-value-accessor.ts +1 -1
package/README.md
CHANGED
|
@@ -49,3 +49,4 @@ export const config: Config = {
|
|
|
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. |
|
|
50
50
|
| `outputType` | Specifies the type of output to be generated. It can take one of the following values: <br />1. `component`: Generates all the component wrappers to be declared on an Angular module. This option is required for Stencil projects using the `dist` hydrated output.<br /> 2. `scam`: Generates a separate Angular module for each component.<br /> 3. `standalone`: Generates standalone component wrappers.<br /> Both `scam` and `standalone` options are compatible with the `dist-custom-elements` output. <br />Note: Please choose the appropriate `outputType` based on your project's requirements and the desired output structure. Defaults to `component`. |
|
|
51
51
|
| `customElementsDir` | This is the directory where the custom elements are imported from when using the [Custom Elements Bundle](https://stenciljs.com/docs/custom-elements). Defaults to the `components` directory. Only applies for `outputType: "scam"` or `outputType: "standalone"`. |
|
|
52
|
+
| `inlineProperties` | Experimental. When true, tries to inline the properties of components. This is required to enable Angular Language Service to type-check and show jsdocs when using the components in html-templates. |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ComponentCompilerEvent } from '@stencil/core/internal';
|
|
1
|
+
import type { ComponentCompilerEvent, ComponentCompilerProperty } from '@stencil/core/internal';
|
|
2
2
|
import type { OutputType } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Creates an Angular component declaration from formatted Stencil compiler metadata.
|
|
@@ -9,9 +9,10 @@ import type { OutputType } from './types';
|
|
|
9
9
|
* @param methods The methods of the Stencil component. (e.g. ['myMethod']).
|
|
10
10
|
* @param includeImportCustomElements Whether to define the component as a custom element.
|
|
11
11
|
* @param standalone Whether to define the component as a standalone component.
|
|
12
|
+
* @param inlineComponentProps List of properties that should be inlined into the component definition.
|
|
12
13
|
* @returns The component declaration as a string.
|
|
13
14
|
*/
|
|
14
|
-
export declare const createAngularComponentDefinition: (tagName: string, inputs: readonly string[], outputs: readonly string[], methods: readonly string[], includeImportCustomElements?: boolean, standalone?: boolean) => string;
|
|
15
|
+
export declare const createAngularComponentDefinition: (tagName: string, inputs: readonly string[], outputs: readonly string[], methods: readonly string[], includeImportCustomElements?: boolean, standalone?: boolean, inlineComponentProps?: readonly ComponentCompilerProperty[]) => string;
|
|
15
16
|
/**
|
|
16
17
|
* Creates the component interface type definition.
|
|
17
18
|
* @param outputType The output type.
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import { createComponentEventTypeImports, dashToPascalCase, formatToQuotedList } from './utils';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a property declaration.
|
|
4
|
+
*
|
|
5
|
+
* @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration.
|
|
6
|
+
* @param type The name of the type (e.g. 'string')
|
|
7
|
+
* @returns The property declaration as a string.
|
|
8
|
+
*/
|
|
9
|
+
function createPropertyDeclaration(prop, type) {
|
|
10
|
+
const comment = createDocComment(prop.docs);
|
|
11
|
+
let eventName = prop.name;
|
|
12
|
+
if (/[-/]/.test(prop.name)) {
|
|
13
|
+
// If a member name includes a dash or a forward slash, we need to wrap it in quotes.
|
|
14
|
+
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212
|
|
15
|
+
eventName = `'${prop.name}'`;
|
|
16
|
+
}
|
|
17
|
+
return `${comment.length > 0 ? ` ${comment}` : ''}
|
|
18
|
+
${eventName}: ${type};`;
|
|
19
|
+
}
|
|
2
20
|
/**
|
|
3
21
|
* Creates an Angular component declaration from formatted Stencil compiler metadata.
|
|
4
22
|
*
|
|
@@ -8,9 +26,10 @@ import { createComponentEventTypeImports, dashToPascalCase, formatToQuotedList }
|
|
|
8
26
|
* @param methods The methods of the Stencil component. (e.g. ['myMethod']).
|
|
9
27
|
* @param includeImportCustomElements Whether to define the component as a custom element.
|
|
10
28
|
* @param standalone Whether to define the component as a standalone component.
|
|
29
|
+
* @param inlineComponentProps List of properties that should be inlined into the component definition.
|
|
11
30
|
* @returns The component declaration as a string.
|
|
12
31
|
*/
|
|
13
|
-
export const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false) => {
|
|
32
|
+
export const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false, inlineComponentProps = []) => {
|
|
14
33
|
const tagNameAsPascal = dashToPascalCase(tagName);
|
|
15
34
|
const hasInputs = inputs.length > 0;
|
|
16
35
|
const hasOutputs = outputs.length > 0;
|
|
@@ -36,6 +55,8 @@ export const createAngularComponentDefinition = (tagName, inputs, outputs, metho
|
|
|
36
55
|
if (standalone && includeImportCustomElements) {
|
|
37
56
|
standaloneOption = `\n standalone: true`;
|
|
38
57
|
}
|
|
58
|
+
const propertyDeclarations = inlineComponentProps.map((m) => createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`));
|
|
59
|
+
const propertiesDeclarationText = ['protected el: HTMLElement;', ...propertyDeclarations].join('\n ');
|
|
39
60
|
/**
|
|
40
61
|
* Notes on the generated output:
|
|
41
62
|
* - We disable @angular-eslint/no-inputs-metadata-property, so that
|
|
@@ -52,7 +73,7 @@ export const createAngularComponentDefinition = (tagName, inputs, outputs, metho
|
|
|
52
73
|
inputs: [${formattedInputs}],${standaloneOption}
|
|
53
74
|
})
|
|
54
75
|
export class ${tagNameAsPascal} {
|
|
55
|
-
|
|
76
|
+
${propertiesDeclarationText}
|
|
56
77
|
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
57
78
|
c.detach();
|
|
58
79
|
this.el = r.nativeElement;${hasOutputs
|
|
@@ -146,17 +167,7 @@ export const createComponentTypeDefinition = (outputType, tagNameAsPascal, event
|
|
|
146
167
|
customElementsDir,
|
|
147
168
|
outputType,
|
|
148
169
|
});
|
|
149
|
-
const eventTypes = publicEvents.map((event) => {
|
|
150
|
-
const comment = createDocComment(event.docs);
|
|
151
|
-
let eventName = event.name;
|
|
152
|
-
if (event.name.includes('-')) {
|
|
153
|
-
// If an event name includes a dash, we need to wrap it in quotes.
|
|
154
|
-
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212
|
|
155
|
-
eventName = `'${event.name}'`;
|
|
156
|
-
}
|
|
157
|
-
return `${comment.length > 0 ? ` ${comment}` : ''}
|
|
158
|
-
${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`;
|
|
159
|
-
});
|
|
170
|
+
const eventTypes = publicEvents.map((event) => createPropertyDeclaration(event, `EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>`));
|
|
160
171
|
const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`;
|
|
161
172
|
const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') +
|
|
162
173
|
`${interfaceDeclaration}${eventTypes.length === 0
|
package/dist/index.cjs.js
CHANGED
|
@@ -144,6 +144,24 @@ const EXTENDED_PATH_REGEX = /^\\\\\?\\/;
|
|
|
144
144
|
const NON_ASCII_REGEX = /[^\x00-\x80]+/;
|
|
145
145
|
const SLASH_REGEX = /\\/g;
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Creates a property declaration.
|
|
149
|
+
*
|
|
150
|
+
* @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration.
|
|
151
|
+
* @param type The name of the type (e.g. 'string')
|
|
152
|
+
* @returns The property declaration as a string.
|
|
153
|
+
*/
|
|
154
|
+
function createPropertyDeclaration(prop, type) {
|
|
155
|
+
const comment = createDocComment(prop.docs);
|
|
156
|
+
let eventName = prop.name;
|
|
157
|
+
if (/[-/]/.test(prop.name)) {
|
|
158
|
+
// If a member name includes a dash or a forward slash, we need to wrap it in quotes.
|
|
159
|
+
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212
|
|
160
|
+
eventName = `'${prop.name}'`;
|
|
161
|
+
}
|
|
162
|
+
return `${comment.length > 0 ? ` ${comment}` : ''}
|
|
163
|
+
${eventName}: ${type};`;
|
|
164
|
+
}
|
|
147
165
|
/**
|
|
148
166
|
* Creates an Angular component declaration from formatted Stencil compiler metadata.
|
|
149
167
|
*
|
|
@@ -153,9 +171,10 @@ const SLASH_REGEX = /\\/g;
|
|
|
153
171
|
* @param methods The methods of the Stencil component. (e.g. ['myMethod']).
|
|
154
172
|
* @param includeImportCustomElements Whether to define the component as a custom element.
|
|
155
173
|
* @param standalone Whether to define the component as a standalone component.
|
|
174
|
+
* @param inlineComponentProps List of properties that should be inlined into the component definition.
|
|
156
175
|
* @returns The component declaration as a string.
|
|
157
176
|
*/
|
|
158
|
-
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false) => {
|
|
177
|
+
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false, inlineComponentProps = []) => {
|
|
159
178
|
const tagNameAsPascal = dashToPascalCase(tagName);
|
|
160
179
|
const hasInputs = inputs.length > 0;
|
|
161
180
|
const hasOutputs = outputs.length > 0;
|
|
@@ -181,6 +200,8 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
|
|
|
181
200
|
if (standalone && includeImportCustomElements) {
|
|
182
201
|
standaloneOption = `\n standalone: true`;
|
|
183
202
|
}
|
|
203
|
+
const propertyDeclarations = inlineComponentProps.map((m) => createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`));
|
|
204
|
+
const propertiesDeclarationText = ['protected el: HTMLElement;', ...propertyDeclarations].join('\n ');
|
|
184
205
|
/**
|
|
185
206
|
* Notes on the generated output:
|
|
186
207
|
* - We disable @angular-eslint/no-inputs-metadata-property, so that
|
|
@@ -197,7 +218,7 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
|
|
|
197
218
|
inputs: [${formattedInputs}],${standaloneOption}
|
|
198
219
|
})
|
|
199
220
|
export class ${tagNameAsPascal} {
|
|
200
|
-
|
|
221
|
+
${propertiesDeclarationText}
|
|
201
222
|
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
202
223
|
c.detach();
|
|
203
224
|
this.el = r.nativeElement;${hasOutputs
|
|
@@ -291,17 +312,7 @@ const createComponentTypeDefinition = (outputType, tagNameAsPascal, events, comp
|
|
|
291
312
|
customElementsDir,
|
|
292
313
|
outputType,
|
|
293
314
|
});
|
|
294
|
-
const eventTypes = publicEvents.map((event) => {
|
|
295
|
-
const comment = createDocComment(event.docs);
|
|
296
|
-
let eventName = event.name;
|
|
297
|
-
if (event.name.includes('-')) {
|
|
298
|
-
// If an event name includes a dash, we need to wrap it in quotes.
|
|
299
|
-
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212
|
|
300
|
-
eventName = `'${event.name}'`;
|
|
301
|
-
}
|
|
302
|
-
return `${comment.length > 0 ? ` ${comment}` : ''}
|
|
303
|
-
${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`;
|
|
304
|
-
});
|
|
315
|
+
const eventTypes = publicEvents.map((event) => createPropertyDeclaration(event, `EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>`));
|
|
305
316
|
const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`;
|
|
306
317
|
const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') +
|
|
307
318
|
`${interfaceDeclaration}${eventTypes.length === 0
|
|
@@ -379,6 +390,7 @@ function copyResources$1(config, resourcesFilesToCopy, directory) {
|
|
|
379
390
|
dest: path__default["default"].join(directory, rf),
|
|
380
391
|
keepDirStructure: false,
|
|
381
392
|
warn: false,
|
|
393
|
+
ignore: [],
|
|
382
394
|
};
|
|
383
395
|
});
|
|
384
396
|
return config.sys.copy(copyTasks, path__default["default"].join(directory));
|
|
@@ -433,6 +445,7 @@ async function copyResources(config, outputTarget) {
|
|
|
433
445
|
dest: destDirectory,
|
|
434
446
|
keepDirStructure: false,
|
|
435
447
|
warn: false,
|
|
448
|
+
ignore: [],
|
|
436
449
|
},
|
|
437
450
|
], srcDirectory);
|
|
438
451
|
}
|
|
@@ -502,10 +515,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
502
515
|
const { componentCorePackage, customElementsDir } = outputTarget;
|
|
503
516
|
for (let cmpMeta of components) {
|
|
504
517
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
505
|
-
const
|
|
518
|
+
const internalProps = [];
|
|
506
519
|
if (cmpMeta.properties) {
|
|
507
|
-
|
|
520
|
+
internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
|
|
508
521
|
}
|
|
522
|
+
const inputs = internalProps.map(mapPropName);
|
|
509
523
|
if (cmpMeta.virtualProperties) {
|
|
510
524
|
inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
|
|
511
525
|
}
|
|
@@ -518,13 +532,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
518
532
|
if (cmpMeta.methods) {
|
|
519
533
|
methods.push(...cmpMeta.methods.filter(filterInternalProps).map(mapPropName));
|
|
520
534
|
}
|
|
535
|
+
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : [];
|
|
521
536
|
/**
|
|
522
537
|
* For each component, we need to generate:
|
|
523
538
|
* 1. The @Component decorated class
|
|
524
539
|
* 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
|
|
525
540
|
* 3. The component interface (using declaration merging for types).
|
|
526
541
|
*/
|
|
527
|
-
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild);
|
|
542
|
+
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
|
|
528
543
|
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
|
|
529
544
|
const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
|
|
530
545
|
proxyFileOutput.push(componentDefinition, '\n');
|
package/dist/index.js
CHANGED
|
@@ -136,6 +136,24 @@ const EXTENDED_PATH_REGEX = /^\\\\\?\\/;
|
|
|
136
136
|
const NON_ASCII_REGEX = /[^\x00-\x80]+/;
|
|
137
137
|
const SLASH_REGEX = /\\/g;
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Creates a property declaration.
|
|
141
|
+
*
|
|
142
|
+
* @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration.
|
|
143
|
+
* @param type The name of the type (e.g. 'string')
|
|
144
|
+
* @returns The property declaration as a string.
|
|
145
|
+
*/
|
|
146
|
+
function createPropertyDeclaration(prop, type) {
|
|
147
|
+
const comment = createDocComment(prop.docs);
|
|
148
|
+
let eventName = prop.name;
|
|
149
|
+
if (/[-/]/.test(prop.name)) {
|
|
150
|
+
// If a member name includes a dash or a forward slash, we need to wrap it in quotes.
|
|
151
|
+
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212
|
|
152
|
+
eventName = `'${prop.name}'`;
|
|
153
|
+
}
|
|
154
|
+
return `${comment.length > 0 ? ` ${comment}` : ''}
|
|
155
|
+
${eventName}: ${type};`;
|
|
156
|
+
}
|
|
139
157
|
/**
|
|
140
158
|
* Creates an Angular component declaration from formatted Stencil compiler metadata.
|
|
141
159
|
*
|
|
@@ -145,9 +163,10 @@ const SLASH_REGEX = /\\/g;
|
|
|
145
163
|
* @param methods The methods of the Stencil component. (e.g. ['myMethod']).
|
|
146
164
|
* @param includeImportCustomElements Whether to define the component as a custom element.
|
|
147
165
|
* @param standalone Whether to define the component as a standalone component.
|
|
166
|
+
* @param inlineComponentProps List of properties that should be inlined into the component definition.
|
|
148
167
|
* @returns The component declaration as a string.
|
|
149
168
|
*/
|
|
150
|
-
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false) => {
|
|
169
|
+
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false, inlineComponentProps = []) => {
|
|
151
170
|
const tagNameAsPascal = dashToPascalCase(tagName);
|
|
152
171
|
const hasInputs = inputs.length > 0;
|
|
153
172
|
const hasOutputs = outputs.length > 0;
|
|
@@ -173,6 +192,8 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
|
|
|
173
192
|
if (standalone && includeImportCustomElements) {
|
|
174
193
|
standaloneOption = `\n standalone: true`;
|
|
175
194
|
}
|
|
195
|
+
const propertyDeclarations = inlineComponentProps.map((m) => createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`));
|
|
196
|
+
const propertiesDeclarationText = ['protected el: HTMLElement;', ...propertyDeclarations].join('\n ');
|
|
176
197
|
/**
|
|
177
198
|
* Notes on the generated output:
|
|
178
199
|
* - We disable @angular-eslint/no-inputs-metadata-property, so that
|
|
@@ -189,7 +210,7 @@ const createAngularComponentDefinition = (tagName, inputs, outputs, methods, inc
|
|
|
189
210
|
inputs: [${formattedInputs}],${standaloneOption}
|
|
190
211
|
})
|
|
191
212
|
export class ${tagNameAsPascal} {
|
|
192
|
-
|
|
213
|
+
${propertiesDeclarationText}
|
|
193
214
|
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
194
215
|
c.detach();
|
|
195
216
|
this.el = r.nativeElement;${hasOutputs
|
|
@@ -283,17 +304,7 @@ const createComponentTypeDefinition = (outputType, tagNameAsPascal, events, comp
|
|
|
283
304
|
customElementsDir,
|
|
284
305
|
outputType,
|
|
285
306
|
});
|
|
286
|
-
const eventTypes = publicEvents.map((event) => {
|
|
287
|
-
const comment = createDocComment(event.docs);
|
|
288
|
-
let eventName = event.name;
|
|
289
|
-
if (event.name.includes('-')) {
|
|
290
|
-
// If an event name includes a dash, we need to wrap it in quotes.
|
|
291
|
-
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212
|
|
292
|
-
eventName = `'${event.name}'`;
|
|
293
|
-
}
|
|
294
|
-
return `${comment.length > 0 ? ` ${comment}` : ''}
|
|
295
|
-
${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`;
|
|
296
|
-
});
|
|
307
|
+
const eventTypes = publicEvents.map((event) => createPropertyDeclaration(event, `EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>`));
|
|
297
308
|
const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`;
|
|
298
309
|
const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') +
|
|
299
310
|
`${interfaceDeclaration}${eventTypes.length === 0
|
|
@@ -371,6 +382,7 @@ function copyResources$1(config, resourcesFilesToCopy, directory) {
|
|
|
371
382
|
dest: path.join(directory, rf),
|
|
372
383
|
keepDirStructure: false,
|
|
373
384
|
warn: false,
|
|
385
|
+
ignore: [],
|
|
374
386
|
};
|
|
375
387
|
});
|
|
376
388
|
return config.sys.copy(copyTasks, path.join(directory));
|
|
@@ -425,6 +437,7 @@ async function copyResources(config, outputTarget) {
|
|
|
425
437
|
dest: destDirectory,
|
|
426
438
|
keepDirStructure: false,
|
|
427
439
|
warn: false,
|
|
440
|
+
ignore: [],
|
|
428
441
|
},
|
|
429
442
|
], srcDirectory);
|
|
430
443
|
}
|
|
@@ -494,10 +507,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
494
507
|
const { componentCorePackage, customElementsDir } = outputTarget;
|
|
495
508
|
for (let cmpMeta of components) {
|
|
496
509
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
497
|
-
const
|
|
510
|
+
const internalProps = [];
|
|
498
511
|
if (cmpMeta.properties) {
|
|
499
|
-
|
|
512
|
+
internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
|
|
500
513
|
}
|
|
514
|
+
const inputs = internalProps.map(mapPropName);
|
|
501
515
|
if (cmpMeta.virtualProperties) {
|
|
502
516
|
inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
|
|
503
517
|
}
|
|
@@ -510,13 +524,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
510
524
|
if (cmpMeta.methods) {
|
|
511
525
|
methods.push(...cmpMeta.methods.filter(filterInternalProps).map(mapPropName));
|
|
512
526
|
}
|
|
527
|
+
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : [];
|
|
513
528
|
/**
|
|
514
529
|
* For each component, we need to generate:
|
|
515
530
|
* 1. The @Component decorated class
|
|
516
531
|
* 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
|
|
517
532
|
* 3. The component interface (using declaration merging for types).
|
|
518
533
|
*/
|
|
519
|
-
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild);
|
|
534
|
+
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
|
|
520
535
|
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
|
|
521
536
|
const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
|
|
522
537
|
proxyFileOutput.push(componentDefinition, '\n');
|
package/dist/output-angular.js
CHANGED
|
@@ -31,6 +31,7 @@ async function copyResources(config, outputTarget) {
|
|
|
31
31
|
dest: destDirectory,
|
|
32
32
|
keepDirStructure: false,
|
|
33
33
|
warn: false,
|
|
34
|
+
ignore: [],
|
|
34
35
|
},
|
|
35
36
|
], srcDirectory);
|
|
36
37
|
}
|
|
@@ -100,10 +101,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
100
101
|
const { componentCorePackage, customElementsDir } = outputTarget;
|
|
101
102
|
for (let cmpMeta of components) {
|
|
102
103
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
103
|
-
const
|
|
104
|
+
const internalProps = [];
|
|
104
105
|
if (cmpMeta.properties) {
|
|
105
|
-
|
|
106
|
+
internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
|
|
106
107
|
}
|
|
108
|
+
const inputs = internalProps.map(mapPropName);
|
|
107
109
|
if (cmpMeta.virtualProperties) {
|
|
108
110
|
inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
|
|
109
111
|
}
|
|
@@ -116,13 +118,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
116
118
|
if (cmpMeta.methods) {
|
|
117
119
|
methods.push(...cmpMeta.methods.filter(filterInternalProps).map(mapPropName));
|
|
118
120
|
}
|
|
121
|
+
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : [];
|
|
119
122
|
/**
|
|
120
123
|
* For each component, we need to generate:
|
|
121
124
|
* 1. The @Component decorated class
|
|
122
125
|
* 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
|
|
123
126
|
* 3. The component interface (using declaration merging for types).
|
|
124
127
|
*/
|
|
125
|
-
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild);
|
|
128
|
+
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
|
|
126
129
|
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
|
|
127
130
|
const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
|
|
128
131
|
proxyFileOutput.push(componentDefinition, '\n');
|
package/dist/types.d.ts
CHANGED
|
@@ -27,6 +27,12 @@ export interface OutputTargetAngular {
|
|
|
27
27
|
* - `standalone` - Generate a component with the `standalone` flag set to `true`.
|
|
28
28
|
*/
|
|
29
29
|
outputType?: OutputType;
|
|
30
|
+
/**
|
|
31
|
+
* Experimental (!)
|
|
32
|
+
* When true, tries to inline the properties of components. This is required to enable Angular Language Service
|
|
33
|
+
* to type-check and show jsdocs when using the components in html-templates.
|
|
34
|
+
*/
|
|
35
|
+
inlineProperties?: boolean;
|
|
30
36
|
}
|
|
31
37
|
export type ValueAccessorTypes = 'text' | 'radio' | 'select' | 'number' | 'boolean';
|
|
32
38
|
export interface ValueAccessorConfig {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stencil/angular-output-target",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Angular output target for @stencil/core components.",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
"prepublishOnly": "pnpm run build",
|
|
18
18
|
"prebuild": "rimraf ./dist && pnpm run test",
|
|
19
19
|
"build": "tsc && pnpm run rollup",
|
|
20
|
+
"dev": "run-p dev:*",
|
|
21
|
+
"dev:build": "tsc --watch --preserveWatchOutput",
|
|
22
|
+
"dev:rollup": "rollup -c --watch --preserveWatchOutput",
|
|
20
23
|
"watch": "tsc --watch",
|
|
21
24
|
"rollup": "rollup -c",
|
|
22
25
|
"version": "pnpm run build",
|
|
@@ -43,6 +46,7 @@
|
|
|
43
46
|
"@types/node": "^18.0.0",
|
|
44
47
|
"jest": "^27.0.0",
|
|
45
48
|
"jest-environment-jsdom": "^27.0.0",
|
|
49
|
+
"npm-run-all2": "^6.2.4",
|
|
46
50
|
"rimraf": "^5.0.0",
|
|
47
51
|
"rollup": "^2.23.1",
|
|
48
52
|
"typescript": "~5.0.4"
|
|
@@ -21,7 +21,7 @@ export class BooleanValueAccessor extends ValueAccessor {
|
|
|
21
21
|
constructor(el: ElementRef) {
|
|
22
22
|
super(el);
|
|
23
23
|
}
|
|
24
|
-
writeValue(value: any) {
|
|
24
|
+
override writeValue(value: any) {
|
|
25
25
|
this.el.nativeElement.checked = this.lastValue = value == null ? false : value;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -21,7 +21,7 @@ export class NumericValueAccessor extends ValueAccessor {
|
|
|
21
21
|
constructor(el: ElementRef) {
|
|
22
22
|
super(el);
|
|
23
23
|
}
|
|
24
|
-
registerOnChange(fn: (_: number | null) => void) {
|
|
24
|
+
override registerOnChange(fn: (_: number | null) => void) {
|
|
25
25
|
super.registerOnChange(value => {
|
|
26
26
|
fn(value === '' ? null : parseFloat(value));
|
|
27
27
|
});
|