@stencil/angular-output-target 0.0.1-dev.11729028168.122837bc → 0.0.1-dev.11730928290.1699ee88
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 +2 -1
- package/dist/index.cjs.js +31 -17
- package/dist/index.js +31 -17
- package/dist/output-angular.js +5 -3
- package/dist/types.d.ts +6 -0
- package/package.json +7 -3
- 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 (/[-/]/.test(event.name)) {
|
|
153
|
-
// If an event name includes a dash or a forward slash, 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
|
|
@@ -43,9 +43,10 @@ function copyResources(config, resourcesFilesToCopy, directory) {
|
|
|
43
43
|
throw new Error('stencil is not properly initialized at this step. Notify the developer');
|
|
44
44
|
}
|
|
45
45
|
const copyTasks = resourcesFilesToCopy.map((rf) => {
|
|
46
|
+
const dest = path.resolve(directory, rf);
|
|
46
47
|
return {
|
|
47
48
|
src: path.join(__dirname, '../resources/control-value-accessors/', rf),
|
|
48
|
-
dest: path.
|
|
49
|
+
dest: path.extname(dest) ? path.dirname(dest) : dest,
|
|
49
50
|
keepDirStructure: false,
|
|
50
51
|
warn: false,
|
|
51
52
|
ignore: [],
|
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 (/[-/]/.test(event.name)) {
|
|
298
|
-
// If an event name includes a dash or a forward slash, 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
|
|
@@ -374,9 +385,10 @@ function copyResources$1(config, resourcesFilesToCopy, directory) {
|
|
|
374
385
|
throw new Error('stencil is not properly initialized at this step. Notify the developer');
|
|
375
386
|
}
|
|
376
387
|
const copyTasks = resourcesFilesToCopy.map((rf) => {
|
|
388
|
+
const dest = path__default["default"].resolve(directory, rf);
|
|
377
389
|
return {
|
|
378
390
|
src: path__default["default"].join(__dirname, '../resources/control-value-accessors/', rf),
|
|
379
|
-
dest: path__default["default"].
|
|
391
|
+
dest: path__default["default"].extname(dest) ? path__default["default"].dirname(dest) : dest,
|
|
380
392
|
keepDirStructure: false,
|
|
381
393
|
warn: false,
|
|
382
394
|
ignore: [],
|
|
@@ -504,10 +516,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
504
516
|
const { componentCorePackage, customElementsDir } = outputTarget;
|
|
505
517
|
for (let cmpMeta of components) {
|
|
506
518
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
507
|
-
const
|
|
519
|
+
const internalProps = [];
|
|
508
520
|
if (cmpMeta.properties) {
|
|
509
|
-
|
|
521
|
+
internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
|
|
510
522
|
}
|
|
523
|
+
const inputs = internalProps.map(mapPropName);
|
|
511
524
|
if (cmpMeta.virtualProperties) {
|
|
512
525
|
inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
|
|
513
526
|
}
|
|
@@ -520,13 +533,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
520
533
|
if (cmpMeta.methods) {
|
|
521
534
|
methods.push(...cmpMeta.methods.filter(filterInternalProps).map(mapPropName));
|
|
522
535
|
}
|
|
536
|
+
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : [];
|
|
523
537
|
/**
|
|
524
538
|
* For each component, we need to generate:
|
|
525
539
|
* 1. The @Component decorated class
|
|
526
540
|
* 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
|
|
527
541
|
* 3. The component interface (using declaration merging for types).
|
|
528
542
|
*/
|
|
529
|
-
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild);
|
|
543
|
+
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
|
|
530
544
|
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
|
|
531
545
|
const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
|
|
532
546
|
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 (/[-/]/.test(event.name)) {
|
|
290
|
-
// If an event name includes a dash or a forward slash, 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
|
|
@@ -366,9 +377,10 @@ function copyResources$1(config, resourcesFilesToCopy, directory) {
|
|
|
366
377
|
throw new Error('stencil is not properly initialized at this step. Notify the developer');
|
|
367
378
|
}
|
|
368
379
|
const copyTasks = resourcesFilesToCopy.map((rf) => {
|
|
380
|
+
const dest = path.resolve(directory, rf);
|
|
369
381
|
return {
|
|
370
382
|
src: path.join(__dirname, '../resources/control-value-accessors/', rf),
|
|
371
|
-
dest: path.
|
|
383
|
+
dest: path.extname(dest) ? path.dirname(dest) : dest,
|
|
372
384
|
keepDirStructure: false,
|
|
373
385
|
warn: false,
|
|
374
386
|
ignore: [],
|
|
@@ -496,10 +508,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
496
508
|
const { componentCorePackage, customElementsDir } = outputTarget;
|
|
497
509
|
for (let cmpMeta of components) {
|
|
498
510
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
499
|
-
const
|
|
511
|
+
const internalProps = [];
|
|
500
512
|
if (cmpMeta.properties) {
|
|
501
|
-
|
|
513
|
+
internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
|
|
502
514
|
}
|
|
515
|
+
const inputs = internalProps.map(mapPropName);
|
|
503
516
|
if (cmpMeta.virtualProperties) {
|
|
504
517
|
inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
|
|
505
518
|
}
|
|
@@ -512,13 +525,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
512
525
|
if (cmpMeta.methods) {
|
|
513
526
|
methods.push(...cmpMeta.methods.filter(filterInternalProps).map(mapPropName));
|
|
514
527
|
}
|
|
528
|
+
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : [];
|
|
515
529
|
/**
|
|
516
530
|
* For each component, we need to generate:
|
|
517
531
|
* 1. The @Component decorated class
|
|
518
532
|
* 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
|
|
519
533
|
* 3. The component interface (using declaration merging for types).
|
|
520
534
|
*/
|
|
521
|
-
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild);
|
|
535
|
+
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
|
|
522
536
|
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
|
|
523
537
|
const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
|
|
524
538
|
proxyFileOutput.push(componentDefinition, '\n');
|
package/dist/output-angular.js
CHANGED
|
@@ -101,10 +101,11 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
101
101
|
const { componentCorePackage, customElementsDir } = outputTarget;
|
|
102
102
|
for (let cmpMeta of components) {
|
|
103
103
|
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName);
|
|
104
|
-
const
|
|
104
|
+
const internalProps = [];
|
|
105
105
|
if (cmpMeta.properties) {
|
|
106
|
-
|
|
106
|
+
internalProps.push(...cmpMeta.properties.filter(filterInternalProps));
|
|
107
107
|
}
|
|
108
|
+
const inputs = internalProps.map(mapPropName);
|
|
108
109
|
if (cmpMeta.virtualProperties) {
|
|
109
110
|
inputs.push(...cmpMeta.virtualProperties.map(mapPropName));
|
|
110
111
|
}
|
|
@@ -117,13 +118,14 @@ ${createImportStatement(componentLibImports, './angular-component-lib/utils')}\n
|
|
|
117
118
|
if (cmpMeta.methods) {
|
|
118
119
|
methods.push(...cmpMeta.methods.filter(filterInternalProps).map(mapPropName));
|
|
119
120
|
}
|
|
121
|
+
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : [];
|
|
120
122
|
/**
|
|
121
123
|
* For each component, we need to generate:
|
|
122
124
|
* 1. The @Component decorated class
|
|
123
125
|
* 2. Optionally the @NgModule decorated class (if includeSingleComponentAngularModules is true)
|
|
124
126
|
* 3. The component interface (using declaration merging for types).
|
|
125
127
|
*/
|
|
126
|
-
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild);
|
|
128
|
+
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps);
|
|
127
129
|
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName);
|
|
128
130
|
const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir);
|
|
129
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.0.1-dev.
|
|
3
|
+
"version": "0.0.1-dev.11730928290.1699ee88",
|
|
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,9 +46,10 @@
|
|
|
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
|
-
"typescript": "~5.0
|
|
52
|
+
"typescript": "~5.6.0"
|
|
49
53
|
},
|
|
50
54
|
"peerDependencies": {
|
|
51
55
|
"@stencil/core": ">=2.0.0 || >=3 || >= 4.0.0-beta.0 || >= 4.0.0"
|
|
@@ -64,5 +68,5 @@
|
|
|
64
68
|
],
|
|
65
69
|
"testURL": "http://localhost"
|
|
66
70
|
},
|
|
67
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "699ee88cb3dc0726b12a985c49a3875b9eb7745a"
|
|
68
72
|
}
|
|
@@ -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
|
});
|