@stencil/angular-output-target
Advanced tools
Comparing version 0.0.1-dev.11729028168.122837bc to 0.0.1-dev.11730913953.1fecd221
@@ -1,2 +0,2 @@ | ||
import type { ComponentCompilerEvent } from '@stencil/core/internal'; | ||
import type { ComponentCompilerEvent, ComponentCompilerProperty } from '@stencil/core/internal'; | ||
import type { OutputType } from './types'; | ||
@@ -12,5 +12,6 @@ /** | ||
* @param standalone Whether to define the component as a standalone component. | ||
* @param inlineComponentProps List of properties that should be inlined into the component definition. | ||
* @returns The component declaration as a string. | ||
*/ | ||
export declare const createAngularComponentDefinition: (tagName: string, inputs: readonly string[], outputs: readonly string[], methods: readonly string[], includeImportCustomElements?: boolean, standalone?: boolean) => string; | ||
export declare const createAngularComponentDefinition: (tagName: string, inputs: readonly string[], outputs: readonly string[], methods: readonly string[], includeImportCustomElements?: boolean, standalone?: boolean, inlineComponentProps?: readonly ComponentCompilerProperty[]) => string; | ||
/** | ||
@@ -17,0 +18,0 @@ * Creates the component interface type definition. |
import { createComponentEventTypeImports, dashToPascalCase, formatToQuotedList } from './utils'; | ||
/** | ||
* Creates a property declaration. | ||
* | ||
* @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration. | ||
* @param type The name of the type (e.g. 'string') | ||
* @returns The property declaration as a string. | ||
*/ | ||
function createPropertyDeclaration(prop, type) { | ||
const comment = createDocComment(prop.docs); | ||
let eventName = prop.name; | ||
if (/[-/]/.test(prop.name)) { | ||
// If a member name includes a dash or a forward slash, we need to wrap it in quotes. | ||
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212 | ||
eventName = `'${prop.name}'`; | ||
} | ||
return `${comment.length > 0 ? ` ${comment}` : ''} | ||
${eventName}: ${type};`; | ||
} | ||
/** | ||
* Creates an Angular component declaration from formatted Stencil compiler metadata. | ||
@@ -11,5 +29,6 @@ * | ||
* @param standalone Whether to define the component as a standalone component. | ||
* @param inlineComponentProps List of properties that should be inlined into the component definition. | ||
* @returns The component declaration as a string. | ||
*/ | ||
export const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false) => { | ||
export const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false, inlineComponentProps = []) => { | ||
const tagNameAsPascal = dashToPascalCase(tagName); | ||
@@ -40,2 +59,4 @@ const hasInputs = inputs.length > 0; | ||
} | ||
const propertyDeclarations = inlineComponentProps.map((m) => createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`)); | ||
const propertiesDeclarationText = ['protected el: HTMLElement;', ...propertyDeclarations].join('\n '); | ||
/** | ||
@@ -57,3 +78,3 @@ * Notes on the generated output: | ||
export class ${tagNameAsPascal} { | ||
protected el: HTMLElement; | ||
${propertiesDeclarationText} | ||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { | ||
@@ -152,13 +173,3 @@ c.detach(); | ||
}); | ||
const eventTypes = publicEvents.map((event) => { | ||
const comment = createDocComment(event.docs); | ||
let eventName = event.name; | ||
if (/[-/]/.test(event.name)) { | ||
// If an event name includes a dash or a forward slash, we need to wrap it in quotes. | ||
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212 | ||
eventName = `'${event.name}'`; | ||
} | ||
return `${comment.length > 0 ? ` ${comment}` : ''} | ||
${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`; | ||
}); | ||
const eventTypes = publicEvents.map((event) => createPropertyDeclaration(event, `EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>`)); | ||
const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`; | ||
@@ -165,0 +176,0 @@ const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') + |
@@ -148,2 +148,20 @@ 'use strict'; | ||
/** | ||
* Creates a property declaration. | ||
* | ||
* @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration. | ||
* @param type The name of the type (e.g. 'string') | ||
* @returns The property declaration as a string. | ||
*/ | ||
function createPropertyDeclaration(prop, type) { | ||
const comment = createDocComment(prop.docs); | ||
let eventName = prop.name; | ||
if (/[-/]/.test(prop.name)) { | ||
// If a member name includes a dash or a forward slash, we need to wrap it in quotes. | ||
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212 | ||
eventName = `'${prop.name}'`; | ||
} | ||
return `${comment.length > 0 ? ` ${comment}` : ''} | ||
${eventName}: ${type};`; | ||
} | ||
/** | ||
* Creates an Angular component declaration from formatted Stencil compiler metadata. | ||
@@ -157,5 +175,6 @@ * | ||
* @param standalone Whether to define the component as a standalone component. | ||
* @param inlineComponentProps List of properties that should be inlined into the component definition. | ||
* @returns The component declaration as a string. | ||
*/ | ||
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false) => { | ||
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false, inlineComponentProps = []) => { | ||
const tagNameAsPascal = dashToPascalCase(tagName); | ||
@@ -186,2 +205,4 @@ const hasInputs = inputs.length > 0; | ||
} | ||
const propertyDeclarations = inlineComponentProps.map((m) => createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`)); | ||
const propertiesDeclarationText = ['protected el: HTMLElement;', ...propertyDeclarations].join('\n '); | ||
/** | ||
@@ -203,3 +224,3 @@ * Notes on the generated output: | ||
export class ${tagNameAsPascal} { | ||
protected el: HTMLElement; | ||
${propertiesDeclarationText} | ||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { | ||
@@ -298,13 +319,3 @@ c.detach(); | ||
}); | ||
const eventTypes = publicEvents.map((event) => { | ||
const comment = createDocComment(event.docs); | ||
let eventName = event.name; | ||
if (/[-/]/.test(event.name)) { | ||
// If an event name includes a dash or a forward slash, we need to wrap it in quotes. | ||
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212 | ||
eventName = `'${event.name}'`; | ||
} | ||
return `${comment.length > 0 ? ` ${comment}` : ''} | ||
${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`; | ||
}); | ||
const eventTypes = publicEvents.map((event) => createPropertyDeclaration(event, `EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>`)); | ||
const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`; | ||
@@ -512,6 +523,7 @@ const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') + | ||
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName); | ||
const inputs = []; | ||
const internalProps = []; | ||
if (cmpMeta.properties) { | ||
inputs.push(...cmpMeta.properties.filter(filterInternalProps).map(mapPropName)); | ||
internalProps.push(...cmpMeta.properties.filter(filterInternalProps)); | ||
} | ||
const inputs = internalProps.map(mapPropName); | ||
if (cmpMeta.virtualProperties) { | ||
@@ -529,2 +541,3 @@ inputs.push(...cmpMeta.virtualProperties.map(mapPropName)); | ||
} | ||
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : []; | ||
/** | ||
@@ -536,3 +549,3 @@ * For each component, we need to generate: | ||
*/ | ||
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild); | ||
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps); | ||
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName); | ||
@@ -539,0 +552,0 @@ const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir); |
@@ -140,2 +140,20 @@ import path from 'path'; | ||
/** | ||
* Creates a property declaration. | ||
* | ||
* @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration. | ||
* @param type The name of the type (e.g. 'string') | ||
* @returns The property declaration as a string. | ||
*/ | ||
function createPropertyDeclaration(prop, type) { | ||
const comment = createDocComment(prop.docs); | ||
let eventName = prop.name; | ||
if (/[-/]/.test(prop.name)) { | ||
// If a member name includes a dash or a forward slash, we need to wrap it in quotes. | ||
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212 | ||
eventName = `'${prop.name}'`; | ||
} | ||
return `${comment.length > 0 ? ` ${comment}` : ''} | ||
${eventName}: ${type};`; | ||
} | ||
/** | ||
* Creates an Angular component declaration from formatted Stencil compiler metadata. | ||
@@ -149,5 +167,6 @@ * | ||
* @param standalone Whether to define the component as a standalone component. | ||
* @param inlineComponentProps List of properties that should be inlined into the component definition. | ||
* @returns The component declaration as a string. | ||
*/ | ||
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false) => { | ||
const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false, standalone = false, inlineComponentProps = []) => { | ||
const tagNameAsPascal = dashToPascalCase(tagName); | ||
@@ -178,2 +197,4 @@ const hasInputs = inputs.length > 0; | ||
} | ||
const propertyDeclarations = inlineComponentProps.map((m) => createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`)); | ||
const propertiesDeclarationText = ['protected el: HTMLElement;', ...propertyDeclarations].join('\n '); | ||
/** | ||
@@ -195,3 +216,3 @@ * Notes on the generated output: | ||
export class ${tagNameAsPascal} { | ||
protected el: HTMLElement; | ||
${propertiesDeclarationText} | ||
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { | ||
@@ -290,13 +311,3 @@ c.detach(); | ||
}); | ||
const eventTypes = publicEvents.map((event) => { | ||
const comment = createDocComment(event.docs); | ||
let eventName = event.name; | ||
if (/[-/]/.test(event.name)) { | ||
// If an event name includes a dash or a forward slash, we need to wrap it in quotes. | ||
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212 | ||
eventName = `'${event.name}'`; | ||
} | ||
return `${comment.length > 0 ? ` ${comment}` : ''} | ||
${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`; | ||
}); | ||
const eventTypes = publicEvents.map((event) => createPropertyDeclaration(event, `EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>`)); | ||
const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`; | ||
@@ -504,6 +515,7 @@ const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') + | ||
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName); | ||
const inputs = []; | ||
const internalProps = []; | ||
if (cmpMeta.properties) { | ||
inputs.push(...cmpMeta.properties.filter(filterInternalProps).map(mapPropName)); | ||
internalProps.push(...cmpMeta.properties.filter(filterInternalProps)); | ||
} | ||
const inputs = internalProps.map(mapPropName); | ||
if (cmpMeta.virtualProperties) { | ||
@@ -521,2 +533,3 @@ inputs.push(...cmpMeta.virtualProperties.map(mapPropName)); | ||
} | ||
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : []; | ||
/** | ||
@@ -528,3 +541,3 @@ * For each component, we need to generate: | ||
*/ | ||
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild); | ||
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps); | ||
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName); | ||
@@ -531,0 +544,0 @@ const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir); |
@@ -104,6 +104,7 @@ import path from 'path'; | ||
const tagNameAsPascal = dashToPascalCase(cmpMeta.tagName); | ||
const inputs = []; | ||
const internalProps = []; | ||
if (cmpMeta.properties) { | ||
inputs.push(...cmpMeta.properties.filter(filterInternalProps).map(mapPropName)); | ||
internalProps.push(...cmpMeta.properties.filter(filterInternalProps)); | ||
} | ||
const inputs = internalProps.map(mapPropName); | ||
if (cmpMeta.virtualProperties) { | ||
@@ -121,2 +122,3 @@ inputs.push(...cmpMeta.virtualProperties.map(mapPropName)); | ||
} | ||
const inlineComponentProps = outputTarget.inlineProperties ? internalProps : []; | ||
/** | ||
@@ -128,3 +130,3 @@ * For each component, we need to generate: | ||
*/ | ||
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild); | ||
const componentDefinition = createAngularComponentDefinition(cmpMeta.tagName, inputs, outputs, methods, isCustomElementsBuild, isStandaloneBuild, inlineComponentProps); | ||
const moduleDefinition = generateAngularModuleForComponent(cmpMeta.tagName); | ||
@@ -131,0 +133,0 @@ const componentTypeDefinition = createComponentTypeDefinition(outputType, tagNameAsPascal, cmpMeta.events, componentCorePackage, customElementsDir); |
@@ -30,2 +30,8 @@ /** | ||
outputType?: OutputType; | ||
/** | ||
* 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. | ||
*/ | ||
inlineProperties?: boolean; | ||
} | ||
@@ -32,0 +38,0 @@ export type ValueAccessorTypes = 'text' | 'radio' | 'select' | 'number' | 'boolean'; |
{ | ||
"name": "@stencil/angular-output-target", | ||
"version": "0.0.1-dev.11729028168.122837bc", | ||
"version": "0.0.1-dev.11730913953.1fecd221", | ||
"description": "Angular output target for @stencil/core components.", | ||
@@ -20,2 +20,5 @@ "main": "dist/index.cjs.js", | ||
"build": "tsc && pnpm run rollup", | ||
"dev": "run-p dev:*", | ||
"dev:build": "tsc --watch --preserveWatchOutput", | ||
"dev:rollup": "rollup -c --watch --preserveWatchOutput", | ||
"watch": "tsc --watch", | ||
@@ -47,5 +50,6 @@ "rollup": "rollup -c", | ||
"jest-environment-jsdom": "^27.0.0", | ||
"npm-run-all2": "^6.2.4", | ||
"rimraf": "^5.0.0", | ||
"rollup": "^2.23.1", | ||
"typescript": "~5.0.4" | ||
"typescript": "~5.6.0" | ||
}, | ||
@@ -69,3 +73,3 @@ "peerDependencies": { | ||
}, | ||
"gitHead": "22837bc3a4015b4295b8effa7aad77728e082a79" | ||
"gitHead": "fecd221ccc756da90b0c2e29d29b7a0ca9e5ef26" | ||
} |
@@ -52,1 +52,2 @@ # @stencil/angular-output-target | ||
| `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"`. | | ||
| `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. | |
@@ -24,5 +24,5 @@ import { Directive, ElementRef } from '@angular/core'; | ||
} | ||
writeValue(value: any) { | ||
override writeValue(value: any) { | ||
this.el.nativeElement.checked = this.lastValue = value == null ? false : value; | ||
} | ||
} |
@@ -24,3 +24,3 @@ import { Directive, ElementRef } from '@angular/core'; | ||
} | ||
registerOnChange(fn: (_: number | null) => void) { | ||
override registerOnChange(fn: (_: number | null) => void) { | ||
super.registerOnChange(value => { | ||
@@ -27,0 +27,0 @@ fn(value === '' ? null : parseFloat(value)); |
109085
2096
53
9