diff --git a/packages/elements-angular/package.json b/packages/elements-angular/package.json index 78360179da..2379924bee 100644 --- a/packages/elements-angular/package.json +++ b/packages/elements-angular/package.json @@ -46,6 +46,22 @@ "es2015": "./dist/fesm2015/inovex.de-elements-angular.mjs", "node": "./dist/fesm2015/inovex.de-elements-angular.mjs", "default": "./dist/fesm2020/inovex.de-elements-angular.mjs" + }, + "./shared": { + "types": "./dist/shared/index.d.ts", + "esm2020": "./dist/esm2020/shared/inovex.de-elements-angular-shared.mjs", + "es2020": "./dist/fesm2020/inovex.de-elements-angular-shared.mjs", + "es2015": "./dist/fesm2015/inovex.de-elements-angular-shared.mjs", + "node": "./dist/fesm2015/inovex.de-elements-angular-shared.mjs", + "default": "./dist/fesm2020/inovex.de-elements-angular-shared.mjs" + }, + "./standalone": { + "types": "./dist/standalone/index.d.ts", + "esm2020": "./dist/esm2020/standalone/inovex.de-elements-angular-standalone.mjs", + "es2020": "./dist/fesm2020/inovex.de-elements-angular-standalone.mjs", + "es2015": "./dist/fesm2015/inovex.de-elements-angular-standalone.mjs", + "node": "./dist/fesm2015/inovex.de-elements-angular-standalone.mjs", + "default": "./dist/fesm2020/inovex.de-elements-angular-standalone.mjs" } } } diff --git a/packages/elements-angular/shared/ng-package.json b/packages/elements-angular/shared/ng-package.json new file mode 100644 index 0000000000..d517c5db01 --- /dev/null +++ b/packages/elements-angular/shared/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "./../node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "src/index.ts" + } +} diff --git a/packages/elements-angular/shared/src/directives/control-value-accesors/boolean-value-accessor.directive.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/boolean-value-accessor.directive.ts new file mode 100644 index 0000000000..0b40704005 --- /dev/null +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/boolean-value-accessor.directive.ts @@ -0,0 +1,21 @@ +import { Directive, ElementRef, HostListener } from '@angular/core'; +import { ValueAccessorDirective } from './value-accessor.directive'; + +export const booleanDirectiveSelector = + 'ino-checkbox,ino-control-item[role="checkbox"],ino-switch'; + +@Directive() +export class BooleanValueAccessorDirective extends ValueAccessorDirective { + constructor(el: ElementRef) { + super(el); + } + + @HostListener('checkedChange', ['$event.detail']) + _handleInoChange(value: boolean) { + this.handleChangeEvent(value); + } + + override writeValue(value: boolean): void { + this.el.nativeElement.checked = this.lastValue = value == null ? '' : value; + } +} diff --git a/packages/elements-angular/shared/src/directives/control-value-accesors/fs-value-accessor.directive.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/fs-value-accessor.directive.ts new file mode 100644 index 0000000000..647392d6cb --- /dev/null +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/fs-value-accessor.directive.ts @@ -0,0 +1,39 @@ +import { Directive, ElementRef, HostListener } from '@angular/core'; +import { ValueAccessorDirective } from './value-accessor.directive'; + +export const fsDirectiveSelector = 'ino-input-file,ino-input[type=file]'; + +@Directive() +export class FsValueAccessorDirective extends ValueAccessorDirective { + constructor(el: ElementRef) { + super(el); + } + + @HostListener('changeFile', ['$event.detail']) + _handleInputEvent(value: any): void { + if (this.el.nativeElement.multiple) { + this.handleChangeEvent(value.files); + } else { + this.handleChangeEvent(value.files[0]); + } + } + + override writeValue(value: any): void { + if (value instanceof FileList) { + this.el.nativeElement.files = value; + } else if (Array.isArray(value) && !value.length) { + this.el.nativeElement.files = null; + } else if (value === null) { + this.el.nativeElement.files = null; + } else { + // Since we cannot manually construct a FileList instance, we have to ignore + // any attempt to push a non-FileList instance into the input. + if (console && console.warn && console.log) { + console.warn( + 'Ignoring attempt to assign non-FileList to input[type=file].', + ); + console.log('Value:', value); + } + } + } +} diff --git a/packages/elements-angular/shared/src/directives/control-value-accesors/index.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/index.ts new file mode 100644 index 0000000000..5875c62776 --- /dev/null +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/index.ts @@ -0,0 +1,6 @@ +export * from './boolean-value-accessor.directive'; +export * from './fs-value-accessor.directive'; +export * from './numeric-value-accessor.directive'; +export * from './radio-value-accessor.directive'; +export * from './range-value-accessor.directive'; +export * from './text-value-accessor.directive'; diff --git a/packages/elements-angular/shared/src/directives/control-value-accesors/numeric-value-accessor.directive.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/numeric-value-accessor.directive.ts new file mode 100644 index 0000000000..eab7303b06 --- /dev/null +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/numeric-value-accessor.directive.ts @@ -0,0 +1,23 @@ +import { HostListener, ElementRef, Directive } from '@angular/core'; +import { ValueAccessorDirective } from './value-accessor.directive'; + +export const numericDirectiveSelector = + 'ino-input[type=number],ino-range:not([ranged])'; + +@Directive() +export class NumericValueAccessorDirective extends ValueAccessorDirective { + constructor(el: ElementRef) { + super(el); + } + + @HostListener('valueChange', ['$event.detail']) + handleInputEvent(value: number): void { + this.handleChangeEvent(value); + } + + registerOnChange(fn: (_: number | null) => void): void { + super.registerOnChange((value: string) => { + fn(value === '' ? null : parseFloat(value)); + }); + } +} diff --git a/packages/elements-angular/shared/src/directives/control-value-accesors/radio-value-accessor.directive.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/radio-value-accessor.directive.ts new file mode 100644 index 0000000000..9d71e6f630 --- /dev/null +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/radio-value-accessor.directive.ts @@ -0,0 +1,21 @@ +import { Directive, ElementRef, HostListener } from '@angular/core'; +import { ValueAccessorDirective } from './value-accessor.directive'; + +export const radioDirectiveSelector = + 'ino-radio,ino-control-item[role="radio"]'; + +@Directive() +export class RadioValueAccessorDirective extends ValueAccessorDirective { + constructor(el: ElementRef) { + super(el); + } + + @HostListener('checkedChange', ['$event.detail']) + _handleInoChange(value: boolean): void { + this.handleChangeEvent(value); + } + + override writeValue(value: boolean): void { + this.el.nativeElement.checked = this.lastValue = value == null ? '' : value; + } +} diff --git a/packages/elements-angular/shared/src/directives/control-value-accesors/range-value-accessor.directive.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/range-value-accessor.directive.ts new file mode 100644 index 0000000000..07eb039698 --- /dev/null +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/range-value-accessor.directive.ts @@ -0,0 +1,68 @@ +import { Directive, ElementRef, HostListener } from '@angular/core'; +import { ControlValueAccessor } from '@angular/forms'; + +type ValueType = 'start' | 'end'; + +export const rangeDirectiveSelector = 'ino-range[ranged=true]'; + +@Directive() +export class RangeValueAccessorDirective implements ControlValueAccessor { + private lastValueStart: number | undefined; + private lastValueEnd: number | undefined; + private lastValueWrittenTo: ValueType | undefined; + + constructor(private el: ElementRef) {} + + writeValue(value: number): void { + if (this.lastValueWrittenTo === 'start') + this.el.nativeElement.valueStart = value; + + if (this.lastValueWrittenTo === 'end') + this.el.nativeElement.valueEnd = value; + } + + @HostListener('valueStartChange', ['$event.detail']) + handleValueStartChange(value: number): void { + this.handleValueStartEndChange('start', value); + } + + @HostListener('valueEndChange', ['$event.detail']) + handleValueEndChange(value: number): void { + this.handleValueStartEndChange('end', value); + } + + private handleValueStartEndChange( + type: 'start' | 'end', + value: number, + ): void { + if (type === 'start' && value !== this.lastValueStart) { + this.lastValueStart = value; + this.lastValueWrittenTo = 'start'; + this.writeValue(value); + } + + if (type === 'end' && value !== this.lastValueEnd) { + this.lastValueEnd = value; + this.lastValueWrittenTo = 'end'; + this.writeValue(value); + } + } + + setDisabledState(isDisabled: boolean): void { + this.el.nativeElement.disabled = isDisabled; + } + + registerOnChange(fn: (value: number) => void) { + this.onChange = fn; + } + registerOnTouched(fn: () => void) { + this.onTouched = fn; + } + + private onChange: (value: any) => void = () => { + /**/ + }; + private onTouched: () => void = () => { + /**/ + }; +} diff --git a/packages/elements-angular/shared/src/directives/control-value-accesors/text-value-accessor.directive.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/text-value-accessor.directive.ts new file mode 100644 index 0000000000..42d42c7898 --- /dev/null +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/text-value-accessor.directive.ts @@ -0,0 +1,22 @@ +import { Directive, ElementRef, HostListener } from '@angular/core'; +import { ValueAccessorDirective } from './value-accessor.directive'; + +export const textDirectiveSelector = + 'ino-autocomplete,ino-currency-input,ino-input:not([type=number]):not([type=file]),ino-markdown-editor,ino-textarea,ino-select,ino-datepicker,ino-segment-group'; + +@Directive() +export class TextValueAccessorDirective extends ValueAccessorDirective { + constructor(el: ElementRef) { + super(el); + } + + @HostListener('valueChange', ['$event.detail']) + _handleInputEvent(value: string): void { + this.handleChangeEvent(value); + } + + @HostListener('inoBlur') + _handleInoBlur() { + this.handleBlurEvent(); + } +} diff --git a/packages/elements-angular/src/directives/control-value-accesors/value-accessor.directive.ts b/packages/elements-angular/shared/src/directives/control-value-accesors/value-accessor.directive.ts similarity index 93% rename from packages/elements-angular/src/directives/control-value-accesors/value-accessor.directive.ts rename to packages/elements-angular/shared/src/directives/control-value-accesors/value-accessor.directive.ts index bd1060faef..5f448094b7 100644 --- a/packages/elements-angular/src/directives/control-value-accesors/value-accessor.directive.ts +++ b/packages/elements-angular/shared/src/directives/control-value-accesors/value-accessor.directive.ts @@ -1,6 +1,7 @@ -import { ElementRef } from '@angular/core'; +import { Directive, ElementRef } from '@angular/core'; import { ControlValueAccessor } from '@angular/forms'; +@Directive() export class ValueAccessorDirective implements ControlValueAccessor { protected lastValue: any; constructor(protected el: ElementRef) {} diff --git a/packages/elements-angular/shared/src/index.ts b/packages/elements-angular/shared/src/index.ts new file mode 100644 index 0000000000..74399d157e --- /dev/null +++ b/packages/elements-angular/shared/src/index.ts @@ -0,0 +1,2 @@ +export * from './directives/control-value-accesors'; +export * from './utils/app-initialize'; diff --git a/packages/elements-angular/src/app-initialize.ts b/packages/elements-angular/shared/src/utils/app-initialize.ts similarity index 100% rename from packages/elements-angular/src/app-initialize.ts rename to packages/elements-angular/shared/src/utils/app-initialize.ts diff --git a/packages/elements-angular/src/utils.ts b/packages/elements-angular/shared/src/utils/utils.ts similarity index 100% rename from packages/elements-angular/src/utils.ts rename to packages/elements-angular/shared/src/utils/utils.ts diff --git a/packages/elements-angular/src/directives/control-value-accesors/boolean-value-accessor.directive.ts b/packages/elements-angular/src/directives/control-value-accesors/boolean-value-accessor.directive.ts index 17b6314281..1896572947 100644 --- a/packages/elements-angular/src/directives/control-value-accesors/boolean-value-accessor.directive.ts +++ b/packages/elements-angular/src/directives/control-value-accesors/boolean-value-accessor.directive.ts @@ -1,10 +1,9 @@ -import { Directive, ElementRef, HostListener } from '@angular/core'; +import { Directive } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; - -import { ValueAccessorDirective } from './value-accessor.directive'; +import { booleanDirectiveSelector, BooleanValueAccessorDirective as ProxyDirective } from '@inovex.de/elements-angular/shared'; @Directive({ - selector: 'ino-checkbox,ino-control-item[role="checkbox"],ino-switch', + selector: booleanDirectiveSelector, providers: [ { provide: NG_VALUE_ACCESSOR, @@ -12,18 +11,6 @@ import { ValueAccessorDirective } from './value-accessor.directive'; multi: true, }, ], + standalone: false }) -export class BooleanValueAccessorDirective extends ValueAccessorDirective { - constructor(el: ElementRef) { - super(el); - } - - @HostListener('checkedChange', ['$event.detail']) - _handleInoChange(value: boolean) { - this.handleChangeEvent(value); - } - - override writeValue(value: boolean): void { - this.el.nativeElement.checked = this.lastValue = value == null ? '' : value; - } -} +export class BooleanValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/src/directives/control-value-accesors/fs-value-accessor.directive.ts b/packages/elements-angular/src/directives/control-value-accesors/fs-value-accessor.directive.ts index 7371ae5f51..a5e09c06ca 100644 --- a/packages/elements-angular/src/directives/control-value-accesors/fs-value-accessor.directive.ts +++ b/packages/elements-angular/src/directives/control-value-accesors/fs-value-accessor.directive.ts @@ -1,48 +1,16 @@ -import { Directive, ElementRef, HostListener } from '@angular/core'; +import { Directive } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; - -import { ValueAccessorDirective } from './value-accessor.directive'; +import { fsDirectiveSelector, FsValueAccessorDirective as ProxyDirective } from '@inovex.de/elements-angular/shared'; @Directive({ - selector: 'ino-input-file,ino-input[type=file]', + selector: fsDirectiveSelector, providers: [ { provide: NG_VALUE_ACCESSOR, - useExisting: FsValueAccessorDirective, + useExisting: ProxyDirective, multi: true, }, ], + standalone: false }) -export class FsValueAccessorDirective extends ValueAccessorDirective { - constructor(el: ElementRef) { - super(el); - } - - @HostListener('changeFile', ['$event.detail']) - _handleInputEvent(value: any): void { - if (this.el.nativeElement.multiple) { - this.handleChangeEvent(value.files); - } else { - this.handleChangeEvent(value.files[0]); - } - } - - override writeValue(value: any): void { - if (value instanceof FileList) { - this.el.nativeElement.files = value; - } else if (Array.isArray(value) && !value.length) { - this.el.nativeElement.files = null; - } else if (value === null) { - this.el.nativeElement.files = null; - } else { - // Since we cannot manually construct a FileList instance, we have to ignore - // any attempt to push a non-FileList instance into the input. - if (console && console.warn && console.log) { - console.warn( - 'Ignoring attempt to assign non-FileList to input[type=file].' - ); - console.log('Value:', value); - } - } - } -} +export class FsValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/src/directives/control-value-accesors/numeric-value-accessor.directive.ts b/packages/elements-angular/src/directives/control-value-accesors/numeric-value-accessor.directive.ts index b0ee1c5c3a..188c462e39 100644 --- a/packages/elements-angular/src/directives/control-value-accesors/numeric-value-accessor.directive.ts +++ b/packages/elements-angular/src/directives/control-value-accesors/numeric-value-accessor.directive.ts @@ -1,9 +1,9 @@ -import { Directive, HostListener, ElementRef } from '@angular/core'; +import { Directive } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; -import { ValueAccessorDirective } from "./value-accessor.directive"; +import { numericDirectiveSelector, NumericValueAccessorDirective as ProxyDirective } from '@inovex.de/elements-angular/shared'; @Directive({ - selector: 'ino-input[type=number],ino-range:not([ranged])', + selector: numericDirectiveSelector, providers: [ { provide: NG_VALUE_ACCESSOR, @@ -11,20 +11,6 @@ import { ValueAccessorDirective } from "./value-accessor.directive"; multi: true, }, ], + standalone: false }) -export class NumericValueAccessorDirective extends ValueAccessorDirective { - constructor(el: ElementRef) { - super(el); - } - - @HostListener('valueChange', ['$event.detail']) - handleInputEvent(value: number): void { - this.handleChangeEvent(value); - } - - registerOnChange(fn: (_: number | null) => void): void { - super.registerOnChange((value: string) => { - fn(value === '' ? null : parseFloat(value)); - }); - } -} +export class NumericValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/src/directives/control-value-accesors/radio-value-accessor.directive.ts b/packages/elements-angular/src/directives/control-value-accesors/radio-value-accessor.directive.ts index 074b0cd6b7..6717a01869 100644 --- a/packages/elements-angular/src/directives/control-value-accesors/radio-value-accessor.directive.ts +++ b/packages/elements-angular/src/directives/control-value-accesors/radio-value-accessor.directive.ts @@ -1,10 +1,9 @@ -import { Directive, ElementRef, HostListener } from '@angular/core'; +import { Directive } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; - -import { ValueAccessorDirective } from './value-accessor.directive'; +import { radioDirectiveSelector, RadioValueAccessorDirective as ProxyDirective } from '@inovex.de/elements-angular/shared'; @Directive({ - selector: 'ino-radio,ino-control-item[role="radio"]', + selector: radioDirectiveSelector, providers: [ { provide: NG_VALUE_ACCESSOR, @@ -12,18 +11,6 @@ import { ValueAccessorDirective } from './value-accessor.directive'; multi: true, }, ], + standalone: false }) -export class RadioValueAccessorDirective extends ValueAccessorDirective { - constructor(el: ElementRef) { - super(el); - } - - @HostListener('checkedChange', ['$event.detail']) - _handleInoChange(value: boolean): void { - this.handleChangeEvent(value); - } - - override writeValue(value: boolean): void { - this.el.nativeElement.checked = this.lastValue = value == null ? '' : value; - } -} +export class RadioValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/src/directives/control-value-accesors/range-value-accessor.directive.ts b/packages/elements-angular/src/directives/control-value-accesors/range-value-accessor.directive.ts index fb56cc4eda..7061dc8015 100644 --- a/packages/elements-angular/src/directives/control-value-accesors/range-value-accessor.directive.ts +++ b/packages/elements-angular/src/directives/control-value-accesors/range-value-accessor.directive.ts @@ -1,10 +1,9 @@ -import { Directive, ElementRef, HostListener } from '@angular/core'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; - -type ValueType = 'start' | 'end'; +import { Directive } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { rangeDirectiveSelector, RangeValueAccessorDirective as ProxyDirective } from '@inovex.de/elements-angular/shared'; @Directive({ - selector: 'ino-range[ranged=true]', + selector: rangeDirectiveSelector, providers: [ { provide: NG_VALUE_ACCESSOR, @@ -12,64 +11,6 @@ type ValueType = 'start' | 'end'; multi: true, }, ], + standalone: false }) -export class RangeValueAccessorDirective implements ControlValueAccessor { - private lastValueStart: number | undefined; - private lastValueEnd: number | undefined; - private lastValueWrittenTo: ValueType | undefined; - - constructor(private el: ElementRef) {} - - writeValue(value: number): void { - if (this.lastValueWrittenTo === 'start') - this.el.nativeElement.valueStart = value; - - if (this.lastValueWrittenTo === 'end') - this.el.nativeElement.valueEnd = value; - } - - @HostListener('valueStartChange', ['$event.detail']) - handleValueStartChange(value: number): void { - this.handleValueStartEndChange('start', value); - } - - @HostListener('valueEndChange', ['$event.detail']) - handleValueEndChange(value: number): void { - this.handleValueStartEndChange('end', value); - } - - private handleValueStartEndChange( - type: 'start' | 'end', - value: number, - ): void { - if (type === 'start' && value !== this.lastValueStart) { - this.lastValueStart = value; - this.lastValueWrittenTo = 'start'; - this.writeValue(value); - } - - if (type === 'end' && value !== this.lastValueEnd) { - this.lastValueEnd = value; - this.lastValueWrittenTo = 'end'; - this.writeValue(value); - } - } - - setDisabledState(isDisabled: boolean): void { - this.el.nativeElement.disabled = isDisabled; - } - - registerOnChange(fn: (value: number) => void) { - this.onChange = fn; - } - registerOnTouched(fn: () => void) { - this.onTouched = fn; - } - - private onChange: (value: any) => void = () => { - /**/ - }; - private onTouched: () => void = () => { - /**/ - }; -} +export class RangeValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/src/directives/control-value-accesors/text-value-accessor.directive.ts b/packages/elements-angular/src/directives/control-value-accesors/text-value-accessor.directive.ts index d3a2a25790..b82da80b37 100644 --- a/packages/elements-angular/src/directives/control-value-accesors/text-value-accessor.directive.ts +++ b/packages/elements-angular/src/directives/control-value-accesors/text-value-accessor.directive.ts @@ -1,11 +1,9 @@ -import { Directive, ElementRef, HostListener } from '@angular/core'; +import { Directive } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; - -import { ValueAccessorDirective } from './value-accessor.directive'; +import { textDirectiveSelector, TextValueAccessorDirective as ProxyDirective } from '@inovex.de/elements-angular/shared'; @Directive({ - selector: - 'ino-autocomplete,ino-currency-input,ino-input:not([type=number]):not([type=file]),ino-markdown-editor,ino-textarea,ino-select,ino-datepicker,ino-segment-group', + selector: textDirectiveSelector, providers: [ { provide: NG_VALUE_ACCESSOR, @@ -13,19 +11,6 @@ import { ValueAccessorDirective } from './value-accessor.directive'; multi: true, }, ], + standalone: false }) -export class TextValueAccessorDirective extends ValueAccessorDirective { - constructor(el: ElementRef) { - super(el); - } - - @HostListener('valueChange', ['$event.detail']) - _handleInputEvent(value: string): void { - this.handleChangeEvent(value); - } - - @HostListener('inoBlur') - _handleInoBlur() { - this.handleBlurEvent(); - } -} +export class TextValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/src/ino-elements.module.ts b/packages/elements-angular/src/ino-elements.module.ts index c2040b8f63..a6ff7f3378 100644 --- a/packages/elements-angular/src/ino-elements.module.ts +++ b/packages/elements-angular/src/ino-elements.module.ts @@ -7,8 +7,7 @@ import { import { CommonModule, DOCUMENT } from '@angular/common'; import { InoElementsConfig } from '@inovex.de/elements'; import { DIRECTIVES } from './directives/proxies-list'; - -import { appInitialize, ConfigToken } from './app-initialize'; +import { appInitialize, ConfigToken } from '@inovex.de/elements-angular/shared'; import { BooleanValueAccessorDirective, FsValueAccessorDirective, diff --git a/packages/elements-angular/standalone/ng-package.json b/packages/elements-angular/standalone/ng-package.json new file mode 100644 index 0000000000..d517c5db01 --- /dev/null +++ b/packages/elements-angular/standalone/ng-package.json @@ -0,0 +1,6 @@ +{ + "$schema": "./../node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "src/index.ts" + } +} diff --git a/packages/elements-angular/standalone/src/directives/angular-component-lib/utils.ts b/packages/elements-angular/standalone/src/directives/angular-component-lib/utils.ts new file mode 100644 index 0000000000..58ed93b7d3 --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/angular-component-lib/utils.ts @@ -0,0 +1,57 @@ +/* eslint-disable */ +/* tslint:disable */ +import { fromEvent } from 'rxjs'; + +export const proxyInputs = (Cmp: any, inputs: string[]) => { + const Prototype = Cmp.prototype; + inputs.forEach((item) => { + Object.defineProperty(Prototype, item, { + get() { + return this.el[item]; + }, + set(val: any) { + this.z.runOutsideAngular(() => (this.el[item] = val)); + }, + }); + }); +}; + +export const proxyMethods = (Cmp: any, methods: string[]) => { + const Prototype = Cmp.prototype; + methods.forEach((methodName) => { + Prototype[methodName] = function () { + const args = arguments; + return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args)); + }; + }); +}; + +export const proxyOutputs = (instance: any, el: any, events: string[]) => { + events.forEach((eventName) => (instance[eventName] = fromEvent(el, eventName))); +}; + +export const defineCustomElement = (tagName: string, customElement: any) => { + if (customElement !== undefined && typeof customElements !== 'undefined' && !customElements.get(tagName)) { + customElements.define(tagName, customElement); + } +}; + +// tslint:disable-next-line: only-arrow-functions +export function ProxyCmp(opts: { defineCustomElementFn?: () => void; inputs?: any; methods?: any }) { + const decorator = function (cls: any) { + const { defineCustomElementFn, inputs, methods } = opts; + + if (defineCustomElementFn !== undefined) { + defineCustomElementFn(); + } + + if (inputs) { + proxyInputs(cls, inputs); + } + if (methods) { + proxyMethods(cls, methods); + } + return cls; + }; + return decorator; +} diff --git a/packages/elements-angular/standalone/src/directives/control-value-accesors/boolean-value-accessor.directive.ts b/packages/elements-angular/standalone/src/directives/control-value-accesors/boolean-value-accessor.directive.ts new file mode 100644 index 0000000000..abd6d5fa19 --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/control-value-accesors/boolean-value-accessor.directive.ts @@ -0,0 +1,19 @@ +import { Directive } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { + booleanDirectiveSelector, + BooleanValueAccessorDirective as ProxyDirective, +} from '@inovex.de/elements-angular/shared'; + +@Directive({ + selector: booleanDirectiveSelector, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: BooleanValueAccessorDirective, + multi: true, + }, + ], + standalone: true, +}) +export class BooleanValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/standalone/src/directives/control-value-accesors/fs-value-accessor.directive.ts b/packages/elements-angular/standalone/src/directives/control-value-accesors/fs-value-accessor.directive.ts new file mode 100644 index 0000000000..c93a8b0624 --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/control-value-accesors/fs-value-accessor.directive.ts @@ -0,0 +1,19 @@ +import { Directive } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { + fsDirectiveSelector, + FsValueAccessorDirective as ProxyDirective, +} from '@inovex.de/elements-angular/shared'; + +@Directive({ + selector: fsDirectiveSelector, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: ProxyDirective, + multi: true, + }, + ], + standalone: true, +}) +export class FsValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/standalone/src/directives/control-value-accesors/index.ts b/packages/elements-angular/standalone/src/directives/control-value-accesors/index.ts new file mode 100644 index 0000000000..5875c62776 --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/control-value-accesors/index.ts @@ -0,0 +1,6 @@ +export * from './boolean-value-accessor.directive'; +export * from './fs-value-accessor.directive'; +export * from './numeric-value-accessor.directive'; +export * from './radio-value-accessor.directive'; +export * from './range-value-accessor.directive'; +export * from './text-value-accessor.directive'; diff --git a/packages/elements-angular/standalone/src/directives/control-value-accesors/numeric-value-accessor.directive.ts b/packages/elements-angular/standalone/src/directives/control-value-accesors/numeric-value-accessor.directive.ts new file mode 100644 index 0000000000..40c5341625 --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/control-value-accesors/numeric-value-accessor.directive.ts @@ -0,0 +1,19 @@ +import { Directive } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { + numericDirectiveSelector, + NumericValueAccessorDirective as ProxyDirective, +} from '@inovex.de/elements-angular/shared'; + +@Directive({ + selector: numericDirectiveSelector, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: NumericValueAccessorDirective, + multi: true, + }, + ], + standalone: true, +}) +export class NumericValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/standalone/src/directives/control-value-accesors/radio-value-accessor.directive.ts b/packages/elements-angular/standalone/src/directives/control-value-accesors/radio-value-accessor.directive.ts new file mode 100644 index 0000000000..72e9e25cc5 --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/control-value-accesors/radio-value-accessor.directive.ts @@ -0,0 +1,19 @@ +import { Directive } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { + radioDirectiveSelector, + RadioValueAccessorDirective as ProxyDirective, +} from '@inovex.de/elements-angular/shared'; + +@Directive({ + selector: radioDirectiveSelector, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: RadioValueAccessorDirective, + multi: true, + }, + ], + standalone: true, +}) +export class RadioValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/standalone/src/directives/control-value-accesors/range-value-accessor.directive.ts b/packages/elements-angular/standalone/src/directives/control-value-accesors/range-value-accessor.directive.ts new file mode 100644 index 0000000000..3e569570fe --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/control-value-accesors/range-value-accessor.directive.ts @@ -0,0 +1,19 @@ +import { Directive } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { + rangeDirectiveSelector, + RangeValueAccessorDirective as ProxyDirective, +} from '@inovex.de/elements-angular/shared'; + +@Directive({ + selector: rangeDirectiveSelector, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: RangeValueAccessorDirective, + multi: true, + }, + ], + standalone: true, +}) +export class RangeValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/standalone/src/directives/control-value-accesors/text-value-accessor.directive.ts b/packages/elements-angular/standalone/src/directives/control-value-accesors/text-value-accessor.directive.ts new file mode 100644 index 0000000000..ff0005bb7a --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/control-value-accesors/text-value-accessor.directive.ts @@ -0,0 +1,19 @@ +import { Directive } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { + textDirectiveSelector, + TextValueAccessorDirective as ProxyDirective, +} from '@inovex.de/elements-angular/shared'; + +@Directive({ + selector: textDirectiveSelector, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: TextValueAccessorDirective, + multi: true, + }, + ], + standalone: true, +}) +export class TextValueAccessorDirective extends ProxyDirective {} diff --git a/packages/elements-angular/standalone/src/directives/proxies.ts b/packages/elements-angular/standalone/src/directives/proxies.ts new file mode 100644 index 0000000000..79ddb47ba7 --- /dev/null +++ b/packages/elements-angular/standalone/src/directives/proxies.ts @@ -0,0 +1,1486 @@ +/* tslint:disable */ +/* auto-generated angular directive proxies */ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core'; + +import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils'; + +import type { Components } from '@inovex.de/elements/dist/components'; + +import { defineCustomElement as defineInoAccordion } from '@inovex.de/elements/dist/components/ino-accordion.js'; +import { defineCustomElement as defineInoAutocomplete } from '@inovex.de/elements/dist/components/ino-autocomplete.js'; +import { defineCustomElement as defineInoAvatar } from '@inovex.de/elements/dist/components/ino-avatar.js'; +import { defineCustomElement as defineInoButton } from '@inovex.de/elements/dist/components/ino-button.js'; +import { defineCustomElement as defineInoCard } from '@inovex.de/elements/dist/components/ino-card.js'; +import { defineCustomElement as defineInoCarousel } from '@inovex.de/elements/dist/components/ino-carousel.js'; +import { defineCustomElement as defineInoCarouselSlide } from '@inovex.de/elements/dist/components/ino-carousel-slide.js'; +import { defineCustomElement as defineInoCheckbox } from '@inovex.de/elements/dist/components/ino-checkbox.js'; +import { defineCustomElement as defineInoChip } from '@inovex.de/elements/dist/components/ino-chip.js'; +import { defineCustomElement as defineInoControlItem } from '@inovex.de/elements/dist/components/ino-control-item.js'; +import { defineCustomElement as defineInoCurrencyInput } from '@inovex.de/elements/dist/components/ino-currency-input.js'; +import { defineCustomElement as defineInoDatepicker } from '@inovex.de/elements/dist/components/ino-datepicker.js'; +import { defineCustomElement as defineInoDialog } from '@inovex.de/elements/dist/components/ino-dialog.js'; +import { defineCustomElement as defineInoFab } from '@inovex.de/elements/dist/components/ino-fab.js'; +import { defineCustomElement as defineInoFabSet } from '@inovex.de/elements/dist/components/ino-fab-set.js'; +import { defineCustomElement as defineInoIcon } from '@inovex.de/elements/dist/components/ino-icon.js'; +import { defineCustomElement as defineInoIconButton } from '@inovex.de/elements/dist/components/ino-icon-button.js'; +import { defineCustomElement as defineInoImg } from '@inovex.de/elements/dist/components/ino-img.js'; +import { defineCustomElement as defineInoImgList } from '@inovex.de/elements/dist/components/ino-img-list.js'; +import { defineCustomElement as defineInoInput } from '@inovex.de/elements/dist/components/ino-input.js'; +import { defineCustomElement as defineInoInputFile } from '@inovex.de/elements/dist/components/ino-input-file.js'; +import { defineCustomElement as defineInoLabel } from '@inovex.de/elements/dist/components/ino-label.js'; +import { defineCustomElement as defineInoList } from '@inovex.de/elements/dist/components/ino-list.js'; +import { defineCustomElement as defineInoListDivider } from '@inovex.de/elements/dist/components/ino-list-divider.js'; +import { defineCustomElement as defineInoListItem } from '@inovex.de/elements/dist/components/ino-list-item.js'; +import { defineCustomElement as defineInoMarkdownEditor } from '@inovex.de/elements/dist/components/ino-markdown-editor.js'; +import { defineCustomElement as defineInoMenu } from '@inovex.de/elements/dist/components/ino-menu.js'; +import { defineCustomElement as defineInoNavDrawer } from '@inovex.de/elements/dist/components/ino-nav-drawer.js'; +import { defineCustomElement as defineInoNavItem } from '@inovex.de/elements/dist/components/ino-nav-item.js'; +import { defineCustomElement as defineInoOption } from '@inovex.de/elements/dist/components/ino-option.js'; +import { defineCustomElement as defineInoOptionGroup } from '@inovex.de/elements/dist/components/ino-option-group.js'; +import { defineCustomElement as defineInoPopover } from '@inovex.de/elements/dist/components/ino-popover.js'; +import { defineCustomElement as defineInoProgressBar } from '@inovex.de/elements/dist/components/ino-progress-bar.js'; +import { defineCustomElement as defineInoRadio } from '@inovex.de/elements/dist/components/ino-radio.js'; +import { defineCustomElement as defineInoRadioGroup } from '@inovex.de/elements/dist/components/ino-radio-group.js'; +import { defineCustomElement as defineInoRange } from '@inovex.de/elements/dist/components/ino-range.js'; +import { defineCustomElement as defineInoSegmentButton } from '@inovex.de/elements/dist/components/ino-segment-button.js'; +import { defineCustomElement as defineInoSegmentGroup } from '@inovex.de/elements/dist/components/ino-segment-group.js'; +import { defineCustomElement as defineInoSelect } from '@inovex.de/elements/dist/components/ino-select.js'; +import { defineCustomElement as defineInoSnackbar } from '@inovex.de/elements/dist/components/ino-snackbar.js'; +import { defineCustomElement as defineInoSpinner } from '@inovex.de/elements/dist/components/ino-spinner.js'; +import { defineCustomElement as defineInoSwitch } from '@inovex.de/elements/dist/components/ino-switch.js'; +import { defineCustomElement as defineInoTab } from '@inovex.de/elements/dist/components/ino-tab.js'; +import { defineCustomElement as defineInoTabBar } from '@inovex.de/elements/dist/components/ino-tab-bar.js'; +import { defineCustomElement as defineInoTable } from '@inovex.de/elements/dist/components/ino-table.js'; +import { defineCustomElement as defineInoTableHeaderCell } from '@inovex.de/elements/dist/components/ino-table-header-cell.js'; +import { defineCustomElement as defineInoTextarea } from '@inovex.de/elements/dist/components/ino-textarea.js'; +import { defineCustomElement as defineInoTooltip } from '@inovex.de/elements/dist/components/ino-tooltip.js'; +@ProxyCmp({ + defineCustomElementFn: defineInoAccordion, + inputs: ['accordionTitle', 'expanded'] +}) +@Component({ + selector: 'ino-accordion', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['accordionTitle', 'expanded'], + standalone: true +}) +export class InoAccordion { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['expandedChange']); + } +} + + +export declare interface InoAccordion extends Components.InoAccordion { + /** + * Emits when the user clicks on the icon toggle to change the expanded state. Contains the status in `event.detail`. + */ + expandedChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoAutocomplete, + inputs: ['debounce', 'noOptionsText', 'options', 'value'] +}) +@Component({ + selector: 'ino-autocomplete', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['debounce', 'noOptionsText', 'options', 'value'], + standalone: true +}) +export class InoAutocomplete { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange']); + } +} + + +export declare interface InoAutocomplete extends Components.InoAutocomplete { + /** + * Emits the list item the user clicked on either as a string or +a `{key: string; value: string}` object depending on the provided options. + +Trigger on two occasions: +1. The user clicked on a list-item. +2. The user types in a string that matches an option and blurs the input + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoAvatar, + inputs: ['a11yLabel', 'alt', 'colorSecondary', 'initials', 'interactive', 'loading', 'src', 'variant'] +}) +@Component({ + selector: 'ino-avatar', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['a11yLabel', 'alt', 'colorSecondary', 'initials', 'interactive', 'loading', 'src', 'variant'], + standalone: true +}) +export class InoAvatar { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoAvatar extends Components.InoAvatar {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoButton, + inputs: ['autoFocus', 'dense', 'disabled', 'form', 'loading', 'name', 'type', 'variant'] +}) +@Component({ + selector: 'ino-button', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['autoFocus', 'dense', 'disabled', 'form', 'loading', 'name', 'type', 'variant'], + standalone: true +}) +export class InoButton { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoButton extends Components.InoButton {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoCard, + inputs: ['disableElevation', 'selected'] +}) +@Component({ + selector: 'ino-card', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['disableElevation', 'selected'], + standalone: true +}) +export class InoCard { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoCard extends Components.InoCard {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoCarousel, + inputs: ['autoplay', 'hideButtons', 'infinite', 'intermission', 'reverse', 'value'] +}) +@Component({ + selector: 'ino-carousel', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['autoplay', 'hideButtons', 'infinite', 'intermission', 'reverse', 'value'], + standalone: true +}) +export class InoCarousel { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange']); + } +} + + +export declare interface InoCarousel extends Components.InoCarousel { + /** + * Emits the `value` of the slide that should be displayed after interaction or autoplay interval. + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoCarouselSlide, + inputs: ['selected', 'src', 'value'] +}) +@Component({ + selector: 'ino-carousel-slide', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['selected', 'src', 'value'], + standalone: true +}) +export class InoCarouselSlide { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoCarouselSlide extends Components.InoCarouselSlide {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoCheckbox, + inputs: ['checked', 'disabled', 'indeterminate', 'name', 'selection', 'value'] +}) +@Component({ + selector: 'ino-checkbox', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['checked', 'disabled', 'indeterminate', 'name', 'selection', 'value'], + standalone: true +}) +export class InoCheckbox { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['checkedChange']); + } +} + + +export declare interface InoCheckbox extends Components.InoCheckbox { + /** + * Emits when the user clicks on the checkbox to change the checked state. Contains the status in `event.detail`. + */ + checkedChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoChip, + inputs: ['clickable', 'disabled', 'fill', 'label', 'removable', 'selectable', 'selected', 'value'] +}) +@Component({ + selector: 'ino-chip', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['clickable', 'disabled', 'fill', 'label', 'removable', 'selectable', 'selected', 'value'], + standalone: true +}) +export class InoChip { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['chipClicked', 'chipRemoved']); + } +} + + +export declare interface InoChip extends Components.InoChip { + /** + * Event that emits the `value` as soon as the user clicks on the chip. + */ + chipClicked: EventEmitter>; + /** + * Event that emits the `value` as soon as the user clicks on the remove icon. + +Listen to this event to hide or destroy this chip. + */ + chipRemoved: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoControlItem, + inputs: ['activated', 'checked', 'disabled', 'indeterminate', 'name', 'role', 'secondaryText', 'selected', 'text', 'trailing', 'value'] +}) +@Component({ + selector: 'ino-control-item', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['activated', 'checked', 'disabled', 'indeterminate', 'name', 'role', 'secondaryText', 'selected', 'text', 'trailing', 'value'], + standalone: true +}) +export class InoControlItem { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['checkedChange']); + } +} + + +export declare interface InoControlItem extends Components.InoControlItem { + /** + * Emits when the user clicks on the checkbox or the list item to change the checked state. Contains the status in `event.detail`. + */ + checkedChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoCurrencyInput, + inputs: ['currencyLocale', 'value'] +}) +@Component({ + selector: 'ino-currency-input', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['currencyLocale', 'value'], + standalone: true +}) +export class InoCurrencyInput { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange']); + } +} + + +export declare interface InoCurrencyInput extends Components.InoCurrencyInput { + /** + * Emits when the user types something in. +Contains typed input in `event.detail` + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoDatepicker, + inputs: ['appendTo', 'attachToBody', 'autoFocus', 'dateFormat', 'defaultDate', 'defaultHour', 'defaultMinute', 'disabled', 'error', 'helper', 'helperPersistent', 'helperValidation', 'hourStep', 'inline', 'label', 'max', 'min', 'minuteStep', 'name', 'outline', 'placeholder', 'range', 'required', 'showLabelHint', 'twelveHourTime', 'type', 'value'], + methods: ['redraw', 'setFocus', 'setBlur'] +}) +@Component({ + selector: 'ino-datepicker', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['appendTo', 'attachToBody', 'autoFocus', 'dateFormat', 'defaultDate', 'defaultHour', 'defaultMinute', 'disabled', 'error', 'helper', 'helperPersistent', 'helperValidation', 'hourStep', 'inline', 'label', 'max', 'min', 'minuteStep', 'name', 'outline', 'placeholder', 'range', 'required', 'showLabelHint', 'twelveHourTime', 'type', 'value'], + standalone: true +}) +export class InoDatepicker { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange']); + } +} + + +export declare interface InoDatepicker extends Components.InoDatepicker { + /** + * Emits when the value of the datepicker changes. +The value can be found in `event.detail` + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoDialog, + inputs: ['actionText', 'attachTo', 'bodyText', 'cancelText', 'closeIcon', 'dialogRole', 'dismissible', 'fullwidth', 'headerText', 'icon', 'open'] +}) +@Component({ + selector: 'ino-dialog', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['actionText', 'attachTo', 'bodyText', 'cancelText', 'closeIcon', 'dialogRole', 'dismissible', 'fullwidth', 'headerText', 'icon', 'open'], + standalone: true +}) +export class InoDialog { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['close', 'action', 'dialogOpen']); + } +} + + +import type { DialogCloseAction as IInoDialogDialogCloseAction } from '@inovex.de/elements/dist/components'; +import type { DialogSubmitAction as IInoDialogDialogSubmitAction } from '@inovex.de/elements/dist/components'; + +export declare interface InoDialog extends Components.InoDialog { + /** + * Emits an event upon closing the dialog + */ + close: EventEmitter>; + /** + * Emits an event upon clicking the action button of the dialog + */ + action: EventEmitter>; + /** + * Emits an event when the dialog is opened. + */ + dialogOpen: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoFab, + inputs: ['disabled', 'edgePosition', 'extended', 'icon', 'label', 'mini', 'tooltipPlacement'] +}) +@Component({ + selector: 'ino-fab', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['disabled', 'edgePosition', 'extended', 'icon', 'label', 'mini', 'tooltipPlacement'], + standalone: true +}) +export class InoFab { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoFab extends Components.InoFab {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoFabSet, + inputs: ['dialDirection', 'leftRightLocation', 'openDial', 'topBottomLocation'] +}) +@Component({ + selector: 'ino-fab-set', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['dialDirection', 'leftRightLocation', 'openDial', 'topBottomLocation'], + standalone: true +}) +export class InoFabSet { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoFabSet extends Components.InoFabSet {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoIcon, + inputs: ['clickable', 'colorSecondary', 'icon', 'src', 'svgTitle'] +}) +@Component({ + selector: 'ino-icon', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['clickable', 'colorSecondary', 'icon', 'src', 'svgTitle'], + standalone: true +}) +export class InoIcon { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['clickEl']); + } +} + + +export declare interface InoIcon extends Components.InoIcon { + /** + * Event that emits as soon as the user clicks on the icon. +The event only emits if the property `inoClickable` is true. + */ + clickEl: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoIconButton, + inputs: ['activated', 'attrs', 'autoFocus', 'disabled', 'filled', 'icon', 'type'] +}) +@Component({ + selector: 'ino-icon-button', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['activated', 'attrs', 'autoFocus', 'disabled', 'filled', 'icon', 'type'], + standalone: true +}) +export class InoIconButton { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['clickEl']); + } +} + + +export declare interface InoIconButton extends Components.InoIconButton { + /** + * Event that emits as soon as the user clicks on the icon. +The event only emits if the property `clickable` is true. + */ + clickEl: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoImg, + inputs: ['alt', 'decoding', 'fallbackIcon', 'height', 'imgListItem', 'label', 'ratioHeight', 'ratioWidth', 'rounded', 'sizes', 'src', 'srcset', 'usemap', 'width'] +}) +@Component({ + selector: 'ino-img', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['alt', 'decoding', 'fallbackIcon', 'height', 'imgListItem', 'label', 'ratioHeight', 'ratioWidth', 'rounded', 'sizes', 'src', 'srcset', 'usemap', 'width'], + standalone: true +}) +export class InoImg { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoImg extends Components.InoImg {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoImgList, + inputs: ['encloseLabel', 'masonry'] +}) +@Component({ + selector: 'ino-img-list', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['encloseLabel', 'masonry'], + standalone: true +}) +export class InoImgList { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoImgList extends Components.InoImgList {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoInput, + inputs: ['autoFocus', 'autocomplete', 'dataList', 'disabled', 'error', 'helper', 'helperCharacterCounter', 'helperPersistent', 'helperValidation', 'label', 'max', 'maxlength', 'min', 'name', 'outline', 'pattern', 'placeholder', 'required', 'showLabelHint', 'step', 'type', 'unit', 'value'], + methods: ['getInputElement', 'setFocus', 'setBlur'] +}) +@Component({ + selector: 'ino-input', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['autoFocus', 'autocomplete', 'dataList', 'disabled', 'error', 'helper', 'helperCharacterCounter', 'helperPersistent', 'helperValidation', 'label', 'max', 'maxlength', 'min', 'name', 'outline', 'pattern', 'placeholder', 'required', 'showLabelHint', 'step', 'type', 'unit', 'value'], + standalone: true +}) +export class InoInput { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['inoBlur', 'inoFocus', 'valueChange']); + } +} + + +export declare interface InoInput extends Components.InoInput { + /** + * Emits when the input field is blurred and validates email input + */ + inoBlur: EventEmitter>; + /** + * Emits when the input field is focused + */ + inoFocus: EventEmitter>; + /** + * Emits when the user types something in. +Contains typed input in `event.detail` + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoInputFile, + inputs: ['accept', 'autoFocus', 'disabled', 'dragAndDrop', 'dragAndDropSecondaryText', 'dragAndDropText', 'label', 'multiple', 'name', 'required'] +}) +@Component({ + selector: 'ino-input-file', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['accept', 'autoFocus', 'disabled', 'dragAndDrop', 'dragAndDropSecondaryText', 'dragAndDropText', 'label', 'multiple', 'name', 'required'], + standalone: true +}) +export class InoInputFile { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['changeFile']); + } +} + + +export declare interface InoInputFile extends Components.InoInputFile { + /** + * Emits when the value changes. + */ + changeFile: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoLabel, + inputs: ['disabled', 'for', 'outline', 'required', 'showHint', 'text'] +}) +@Component({ + selector: 'ino-label', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['disabled', 'for', 'outline', 'required', 'showHint', 'text'], + standalone: true +}) +export class InoLabel { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoLabel extends Components.InoLabel {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoList, + inputs: ['avatar', 'dense', 'twoLines'] +}) +@Component({ + selector: 'ino-list', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['avatar', 'dense', 'twoLines'], + standalone: true +}) +export class InoList { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoList extends Components.InoList {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoListDivider, + inputs: ['betweenLists', 'inset', 'padded'] +}) +@Component({ + selector: 'ino-list-divider', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['betweenLists', 'inset', 'padded'], + standalone: true +}) +export class InoListDivider { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoListDivider extends Components.InoListDivider {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoListItem, + inputs: ['activated', 'attrs', 'disabled', 'secondaryText', 'selected', 'text'] +}) +@Component({ + selector: 'ino-list-item', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['activated', 'attrs', 'disabled', 'secondaryText', 'selected', 'text'], + standalone: true +}) +export class InoListItem { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['clickEl']); + } +} + + +export declare interface InoListItem extends Components.InoListItem { + /** + * Emits when the list item is clicked or +the enter/space key if pressed while the item is in focus. +Contains the element itself in `event.detail` + */ + clickEl: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoMarkdownEditor, + inputs: ['initialValue', 'viewMode'] +}) +@Component({ + selector: 'ino-markdown-editor', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['initialValue', 'viewMode'], + standalone: true +}) +export class InoMarkdownEditor { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['viewModeChange', 'valueChange', 'inoBlur']); + } +} + + +import type { ViewModeUnion as IInoMarkdownEditorViewModeUnion } from '@inovex.de/elements/dist/components'; + +export declare interface InoMarkdownEditor extends Components.InoMarkdownEditor { + /** + * Emits when one of the view mode buttons was clicked. +The value of type `ViewMode` can be found in `event.detail` + */ + viewModeChange: EventEmitter>; + /** + * Emits when the value of the markdown editor **blurs**. +The value of type `string` can be found in `event.detail` + */ + valueChange: EventEmitter>; + /** + * Emits when the ino-markdown-editor is blurred + */ + inoBlur: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoMenu, + inputs: ['placement'] +}) +@Component({ + selector: 'ino-menu', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['placement'], + standalone: true +}) +export class InoMenu { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoMenu extends Components.InoMenu {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoNavDrawer, + inputs: ['a11yLabels', 'anchor', 'open', 'variant'] +}) +@Component({ + selector: 'ino-nav-drawer', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['a11yLabels', 'anchor', 'open', 'variant'], + standalone: true +}) +export class InoNavDrawer { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['openChange']); + } +} + + +export declare interface InoNavDrawer extends Components.InoNavDrawer { + /** + * Emits when the user clicks on the drawer toggle icon to change the open state. Contains the status in `event.detail`. + */ + openChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoNavItem, + inputs: ['activated', 'disabled', 'subText', 'text'] +}) +@Component({ + selector: 'ino-nav-item', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['activated', 'disabled', 'subText', 'text'], + standalone: true +}) +export class InoNavItem { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoNavItem extends Components.InoNavItem {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoOption, + inputs: ['disabled', 'selected', 'value'] +}) +@Component({ + selector: 'ino-option', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['disabled', 'selected', 'value'], + standalone: true +}) +export class InoOption { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['clickEl']); + } +} + + +export declare interface InoOption extends Components.InoOption { + /** + * Emits on option click + */ + clickEl: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoOptionGroup, + inputs: ['label'] +}) +@Component({ + selector: 'ino-option-group', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['label'], + standalone: true +}) +export class InoOptionGroup { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoOptionGroup extends Components.InoOptionGroup {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoPopover, + inputs: ['arrow', 'attachToBody', 'colorScheme', 'controlled', 'delay', 'distance', 'followCursor', 'for', 'hideOnBlur', 'hideOnEsc', 'interactive', 'placement', 'trigger', 'visible'], + methods: ['getTippyInstance'] +}) +@Component({ + selector: 'ino-popover', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['arrow', 'attachToBody', 'colorScheme', 'controlled', 'delay', 'distance', 'followCursor', 'for', 'hideOnBlur', 'hideOnEsc', 'interactive', 'placement', 'trigger', 'visible'], + standalone: true +}) +export class InoPopover { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['visibleChanged']); + } +} + + +export declare interface InoPopover extends Components.InoPopover { + /** + * Emits when the popover wants to show (`true`) or hide (`false`) itself. +This is depended on the `trigger` property. +Use this event in controlled-mode (see `controlled`). + +e.g.: `trigger = 'click'` - This events emits with `true` +when the user clicks on the target (slot/`for`/parent-element) +and emits with `false` when the target or the outside is clicked. + */ + visibleChanged: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoProgressBar, + inputs: ['buffer', 'indeterminate', 'label', 'progress'] +}) +@Component({ + selector: 'ino-progress-bar', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['buffer', 'indeterminate', 'label', 'progress'], + standalone: true +}) +export class InoProgressBar { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoProgressBar extends Components.InoProgressBar {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoRadio, + inputs: ['checked', 'disabled', 'name', 'value'] +}) +@Component({ + selector: 'ino-radio', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['checked', 'disabled', 'name', 'value'], + standalone: true +}) +export class InoRadio { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['checkedChange']); + } +} + + +export declare interface InoRadio extends Components.InoRadio { + /** + * Emits when the user interacts with the radio-button. Contains `true` in `event.detail`. +This event will only be emitted if the current state of the radio button is false. + */ + checkedChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoRadioGroup, + inputs: ['alignment', 'value'] +}) +@Component({ + selector: 'ino-radio-group', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['alignment', 'value'], + standalone: true +}) +export class InoRadioGroup { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange']); + } +} + + +export declare interface InoRadioGroup extends Components.InoRadioGroup { + /** + * Emits if the user clicks or navigates (via keyboard) to a `` element within the radio group. +Contains the `value` of the selected ``. + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoRange, + inputs: ['disabled', 'discrete', 'markers', 'max', 'min', 'name', 'ranged', 'step', 'value', 'valueEnd', 'valueStart'], + methods: ['setValueToAriaTextMapperFn'] +}) +@Component({ + selector: 'ino-range', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['disabled', 'discrete', 'markers', 'max', 'min', 'name', 'ranged', 'step', 'value', 'valueEnd', 'valueStart'], + standalone: true +}) +export class InoRange { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange', 'valueStartChange', 'valueEndChange']); + } +} + + +export declare interface InoRange extends Components.InoRange { + /** + * Emits when the value changes (not in ranged mode). + */ + valueChange: EventEmitter>; + /** + * Emits when the start (left) value of the interval changes (in ranged mode). + */ + valueStartChange: EventEmitter>; + /** + * Emits when the end (right) value of the interval changes (in ranged mode). + */ + valueEndChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoSegmentButton, + inputs: ['checked', 'dense', 'disabled', 'name', 'type', 'value'] +}) +@Component({ + selector: 'ino-segment-button', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['checked', 'dense', 'disabled', 'name', 'type', 'value'], + standalone: true +}) +export class InoSegmentButton { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['checkedChange']); + } +} + + +export declare interface InoSegmentButton extends Components.InoSegmentButton { + /** + * Emits if the user interacts with the button. +If the button is disabled or checked, the event will not be emitted. + */ + checkedChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoSegmentGroup, + inputs: ['name', 'value'] +}) +@Component({ + selector: 'ino-segment-group', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['name', 'value'], + standalone: true +}) +export class InoSegmentGroup { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange']); + } +} + + +export declare interface InoSegmentGroup extends Components.InoSegmentGroup { + /** + * Forwards the `checkedChange` events of the `` with its value as the detail. + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoSelect, + inputs: ['disabled', 'error', 'helper', 'helperPersistent', 'helperValidation', 'label', 'name', 'outline', 'required', 'showLabelHint', 'value'] +}) +@Component({ + selector: 'ino-select', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['disabled', 'error', 'helper', 'helperPersistent', 'helperValidation', 'label', 'name', 'outline', 'required', 'showLabelHint', 'value'], + standalone: true +}) +export class InoSelect { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['valueChange']); + } +} + + +export declare interface InoSelect extends Components.InoSelect { + /** + * Emits when a selection changes. Contains new value in `event.detail`. + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoSnackbar, + inputs: ['actionText', 'message', 'stayVisibleOnHover', 'timeout', 'type'] +}) +@Component({ + selector: 'ino-snackbar', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['actionText', 'message', 'stayVisibleOnHover', 'timeout', 'type'], + standalone: true +}) +export class InoSnackbar { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['actionClick', 'hideEl']); + } +} + + +export declare interface InoSnackbar extends Components.InoSnackbar { + /** + * Event that emits as soon as the action button is clicked. + */ + actionClick: EventEmitter>; + /** + * Event that emits as soon as the snackbar hides. +Listen to this event to hide or destroy this element. + */ + hideEl: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoSpinner, + inputs: ['height', 'modal', 'type', 'width'] +}) +@Component({ + selector: 'ino-spinner', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['height', 'modal', 'type', 'width'], + standalone: true +}) +export class InoSpinner { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoSpinner extends Components.InoSpinner {} + + +@ProxyCmp({ + defineCustomElementFn: defineInoSwitch, + inputs: ['checked', 'disabled', 'name'] +}) +@Component({ + selector: 'ino-switch', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['checked', 'disabled', 'name'], + standalone: true +}) +export class InoSwitch { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['checkedChange']); + } +} + + +export declare interface InoSwitch extends Components.InoSwitch { + /** + * Emits when the user clicks on the switch to change the `checked` state. Contains the status in `event.detail`. + */ + checkedChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoTab, + inputs: ['a11yControls', 'a11ySelected', 'icon', 'indicatorContentWidth', 'label', 'stacked'] +}) +@Component({ + selector: 'ino-tab', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['a11yControls', 'a11ySelected', 'icon', 'indicatorContentWidth', 'label', 'stacked'], + standalone: true +}) +export class InoTab { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['interacted']); + } +} + + +export declare interface InoTab extends Components.InoTab { + /** + * Emitted when the user interacts with the tab. +This event is used by the ino-tab-bar. + */ + interacted: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoTabBar, + inputs: ['activeTab', 'autoFocus'] +}) +@Component({ + selector: 'ino-tab-bar', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['activeTab', 'autoFocus'], + standalone: true +}) +export class InoTabBar { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['activeTabChange']); + } +} + + +export declare interface InoTabBar extends Components.InoTabBar { + /** + * Emits when a tab changes. +Contains the index of the activated tab in `event.detail` + */ + activeTabChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoTable, + inputs: ['loading', 'noHover', 'sortColumnId', 'sortDirection', 'stickyHeader'] +}) +@Component({ + selector: 'ino-table', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['loading', 'noHover', 'sortColumnId', 'sortDirection', 'stickyHeader'], + standalone: true +}) +export class InoTable { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['sortChange']); + } +} + + +import type { SortDirectionChangeDetails as IInoTableSortDirectionChangeDetails } from '@inovex.de/elements/dist/components'; + +export declare interface InoTable extends Components.InoTable { + /** + * Emits that the sort direction or column id has changed. + */ + sortChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoTableHeaderCell, + inputs: ['autofocus', 'columnId', 'label', 'notSortable', 'searchIcon', 'searched', 'sortDirection', 'sortStart'], + methods: ['setSearchable', 'setFocus', 'setBlur'] +}) +@Component({ + selector: 'ino-table-header-cell', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['autofocus', 'columnId', 'label', 'notSortable', 'searchIcon', 'searched', 'sortDirection', 'sortStart'], + standalone: true +}) +export class InoTableHeaderCell { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['sortDirectionChange', 'searchFocusChange']); + } +} + + +import type { SortDirectionChangeDetails as IInoTableHeaderCellSortDirectionChangeDetails } from '@inovex.de/elements/dist/components'; + +export declare interface InoTableHeaderCell extends Components.InoTableHeaderCell { + /** + * Emits that the sort direction has been changed. + */ + sortDirectionChange: EventEmitter>; + /** + * Emits that the search field focused (true) or blurred (false). + */ + searchFocusChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoTextarea, + inputs: ['autoFocus', 'autogrow', 'cols', 'disabled', 'label', 'maxlength', 'minlength', 'name', 'outline', 'placeholder', 'required', 'rows', 'showCharacterCounter', 'showLabelHint', 'value'], + methods: ['setFocus', 'setBlur'] +}) +@Component({ + selector: 'ino-textarea', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['autoFocus', 'autogrow', 'cols', 'disabled', 'label', 'maxlength', 'minlength', 'name', 'outline', 'placeholder', 'required', 'rows', 'showCharacterCounter', 'showLabelHint', 'value'], + standalone: true +}) +export class InoTextarea { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + proxyOutputs(this, this.el, ['inoBlur', 'valueChange']); + } +} + + +export declare interface InoTextarea extends Components.InoTextarea { + /** + * Emits when the textarea is blurred and validates email input + */ + inoBlur: EventEmitter>; + /** + * Emits when the user types something in. Contains typed input in `event.detail` + */ + valueChange: EventEmitter>; +} + + +@ProxyCmp({ + defineCustomElementFn: defineInoTooltip, + inputs: ['arrow', 'colorScheme', 'delay', 'for', 'headerText', 'label', 'placement', 'trigger'], + methods: ['getTippyInstance'] +}) +@Component({ + selector: 'ino-tooltip', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '', + // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property + inputs: ['arrow', 'colorScheme', 'delay', 'for', 'headerText', 'label', 'placement', 'trigger'], + standalone: true +}) +export class InoTooltip { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + +export declare interface InoTooltip extends Components.InoTooltip {} + + diff --git a/packages/elements-angular/standalone/src/index.ts b/packages/elements-angular/standalone/src/index.ts new file mode 100644 index 0000000000..2b1e10df36 --- /dev/null +++ b/packages/elements-angular/standalone/src/index.ts @@ -0,0 +1,3 @@ +export * from './directives/control-value-accesors'; +export * from './directives/proxies'; +export * from './providers/elements-angular'; diff --git a/packages/elements-angular/standalone/src/providers/elements-angular.ts b/packages/elements-angular/standalone/src/providers/elements-angular.ts new file mode 100644 index 0000000000..00ef5d4c0c --- /dev/null +++ b/packages/elements-angular/standalone/src/providers/elements-angular.ts @@ -0,0 +1,22 @@ +import { DOCUMENT } from '@angular/common'; +import { APP_INITIALIZER } from '@angular/core'; +import type { Provider } from '@angular/core'; +import { appInitialize, ConfigToken } from '@inovex.de/elements-angular/shared'; +import { InoElementsConfig } from '@inovex.de/elements'; + +export const provideElementsAngular = ( + config?: InoElementsConfig, +): Provider[] => { + return [ + { + provide: ConfigToken, + useValue: config, + }, + { + provide: APP_INITIALIZER, + useFactory: appInitialize, + multi: true, + deps: [ConfigToken, DOCUMENT], + }, + ]; +}; diff --git a/packages/elements-angular/tsconfig.json b/packages/elements-angular/tsconfig.json index 5cab4a1d74..7f04e96a6a 100644 --- a/packages/elements-angular/tsconfig.json +++ b/packages/elements-angular/tsconfig.json @@ -8,7 +8,7 @@ "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "skipLibCheck": false + "skipLibCheck": true }, "files": [], "include": [], diff --git a/packages/elements-angular/tsconfig.lib.prod.json b/packages/elements-angular/tsconfig.lib.prod.json index 2a2faa884c..257e949048 100644 --- a/packages/elements-angular/tsconfig.lib.prod.json +++ b/packages/elements-angular/tsconfig.lib.prod.json @@ -5,5 +5,6 @@ }, "angularCompilerOptions": { "compilationMode": "partial" - } + }, + "files": ["src/index.ts", "standalone/src/index.ts"] } diff --git a/packages/elements/output-targets/angular.ts b/packages/elements/output-targets/angular.ts index 189e33309f..e6bca2c138 100644 --- a/packages/elements/output-targets/angular.ts +++ b/packages/elements/output-targets/angular.ts @@ -6,9 +6,22 @@ const angularTargetPath = join( '../../elements-angular/src/directives', ); -export default angularOutputTarget({ - componentCorePackage: '@inovex.de/elements', - outputType: 'component', - directivesProxyFile: `${angularTargetPath}/proxies.ts`, - directivesArrayFile: `${angularTargetPath}/proxies-list.ts`, -}); +const angularStandaloneTargetPath = join( + __dirname, + '../../elements-angular/standalone/src/directives', +); + +export default [ + angularOutputTarget({ + componentCorePackage: '@inovex.de/elements', + outputType: 'component', + directivesProxyFile: `${angularTargetPath}/proxies.ts`, + directivesArrayFile: `${angularTargetPath}/proxies-list.ts`, + }), + angularOutputTarget({ + componentCorePackage: '@inovex.de/elements', + outputType: 'standalone', + customElementsDir: 'dist/components', + directivesProxyFile: `${angularStandaloneTargetPath}/proxies.ts`, + }), +]; diff --git a/packages/elements/scripts/custom-elements/custom-elements.d.ts b/packages/elements/scripts/custom-elements/custom-elements.d.ts new file mode 100644 index 0000000000..19e169a253 --- /dev/null +++ b/packages/elements/scripts/custom-elements/custom-elements.d.ts @@ -0,0 +1,2 @@ +export * from './index'; +export * from '../types/interface'; diff --git a/packages/elements/scripts/custom-elements/package.json b/packages/elements/scripts/custom-elements/package.json new file mode 100644 index 0000000000..6b715eff92 --- /dev/null +++ b/packages/elements/scripts/custom-elements/package.json @@ -0,0 +1,9 @@ +{ + "name": "@inovex.de/elements/components", + "version": "9.1.0", + "description": "inovex elements components exported as custom elements, extending HTMLElement.", + "main": "./index.js", + "types": "./custom-elements.d.ts", + "private": true, + "sideEffects": false +} diff --git a/packages/elements/stencil.config.ts b/packages/elements/stencil.config.ts index b3c6b78c06..fe429c481b 100644 --- a/packages/elements/stencil.config.ts +++ b/packages/elements/stencil.config.ts @@ -1,6 +1,6 @@ import { Config } from '@stencil/core'; import { sass } from '@stencil/sass'; -import AngularOutputTarget from './output-targets/angular'; +import AngularOutputTargets from './output-targets/angular'; import ReactOutputTarget from './output-targets/react'; import VueOutputTarget from './output-targets/vue'; import JsonDocsOutputTarget from './output-targets/json-docs'; @@ -21,10 +21,23 @@ export const config: Config = { sourceMap: process.env.NODE_ENV === 'development', namespace: 'inovex-elements', taskQueue: 'async', + validatePrimaryPackageOutputTarget: true, outputTargets: [ { type: 'dist', copy: [{ src: 'assets/ino-icon', dest: 'ino-icon' }], + isPrimaryPackageOutputTarget: true, + }, + { + type: 'dist-custom-elements', + customElementsExportBehavior: 'single-export-module', + copy: [ + { + src: '../scripts/custom-elements', + dest: 'dist/components', + warn: true, + }, + ], }, { type: 'docs-readme' }, { @@ -34,7 +47,7 @@ export const config: Config = { 'https://github.com/inovex/elements//tree/master/packages/elements', }, JsonDocsOutputTarget, - AngularOutputTarget, + ...AngularOutputTargets, ReactOutputTarget, VueOutputTarget, ], diff --git a/tsconfig.base.json b/tsconfig.base.json index a8b4614867..23bd7292bc 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -9,6 +9,11 @@ "importHelpers": true, "target": "es2017", "module": "esnext", - "baseUrl": "./" + "baseUrl": "./", + "paths": { + "@inovex.de/elements-angular/shared": [ + "packages/elements-angular/shared/src/index.ts" + ] + } } }