diff --git a/libs/nx/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-dialog.directive.ts.template b/libs/nx/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-dialog.directive.ts.template index f09e1e3e5..752a12c40 100644 --- a/libs/nx/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-dialog.directive.ts.template +++ b/libs/nx/src/generators/ui/libs/ui-command-helm/files/lib/hlm-command-dialog.directive.ts.template @@ -10,7 +10,7 @@ import { HlmCommandDirective } from './hlm-command.directive'; }) export class HlmCommandDialogDirective { private _stateProvider = injectExposesStateProvider({ host: true }); - public state = this._stateProvider?.state ?? signal('closed').asReadonly(); + public state = this._stateProvider.state ?? signal('closed').asReadonly(); private _renderer = inject(Renderer2); private _element = inject(ElementRef); diff --git a/libs/nx/src/generators/ui/libs/ui-dialog-helm/files/lib/hlm-dialog-content.directive.ts.template b/libs/nx/src/generators/ui/libs/ui-dialog-helm/files/lib/hlm-dialog-content.directive.ts.template index 68d1638d7..a4c2dd93d 100644 --- a/libs/nx/src/generators/ui/libs/ui-dialog-helm/files/lib/hlm-dialog-content.directive.ts.template +++ b/libs/nx/src/generators/ui/libs/ui-dialog-helm/files/lib/hlm-dialog-content.directive.ts.template @@ -9,7 +9,7 @@ import { ClassValue } from 'clsx'; export class HlmDialogContentDirective { private _inputs: ClassValue = ''; private _statusProvider = injectExposesStateProvider({ host: true }); - public state = this._statusProvider?.state ?? signal('closed').asReadonly(); + public state = this._statusProvider.state ?? signal('closed').asReadonly(); private _renderer = inject(Renderer2); private _element = inject(ElementRef); diff --git a/libs/nx/src/generators/ui/libs/ui-hover-card-helm/files/lib/hlm-hover-card-content.directive.ts.template b/libs/nx/src/generators/ui/libs/ui-hover-card-helm/files/lib/hlm-hover-card-content.directive.ts.template index 069898f3b..1e653ae96 100644 --- a/libs/nx/src/generators/ui/libs/ui-hover-card-helm/files/lib/hlm-hover-card-content.directive.ts.template +++ b/libs/nx/src/generators/ui/libs/ui-hover-card-helm/files/lib/hlm-hover-card-content.directive.ts.template @@ -11,8 +11,8 @@ export class HlmHoverCardContentDirective { private _inputs: ClassValue = ''; - public readonly state = this._statusProvider?.state ?? signal('closed').asReadonly(); - public readonly side = this._sideProvider?.side ?? signal('bottom').asReadonly(); + public readonly state = this._statusProvider.state ?? signal('closed').asReadonly(); + public readonly side = this._sideProvider.side ?? signal('bottom').asReadonly(); constructor() { effect(() => { diff --git a/libs/nx/src/generators/ui/libs/ui-popover-helm/files/lib/hlm-popover-content.directive.ts.template b/libs/nx/src/generators/ui/libs/ui-popover-helm/files/lib/hlm-popover-content.directive.ts.template index 418938c27..09673eb38 100644 --- a/libs/nx/src/generators/ui/libs/ui-popover-helm/files/lib/hlm-popover-content.directive.ts.template +++ b/libs/nx/src/generators/ui/libs/ui-popover-helm/files/lib/hlm-popover-content.directive.ts.template @@ -9,7 +9,7 @@ import { ClassValue } from 'clsx'; export class HlmPopoverContentDirective { private _inputs: ClassValue = ''; private _stateProvider = injectExposesStateProvider({ host: true }); - public state = this._stateProvider?.state ?? signal('closed'); + public state = this._stateProvider.state ?? signal('closed'); private _renderer = inject(Renderer2); private _element = inject(ElementRef); diff --git a/libs/nx/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-content.directive.ts.template b/libs/nx/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-content.directive.ts.template index c5b9da376..4b27341e6 100644 --- a/libs/nx/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-content.directive.ts.template +++ b/libs/nx/src/generators/ui/libs/ui-sheet-helm/files/lib/hlm-sheet-content.directive.ts.template @@ -30,7 +30,7 @@ export class HlmSheetContentDirective { private _inputs: ClassValue = ''; private _stateProvider = injectExposesStateProvider({ host: true }); private _sideProvider = injectExposedSideProvider({ host: true }); - public state = this._stateProvider?.state ?? signal('closed'); + public state = this._stateProvider.state ?? signal('closed'); private _renderer = inject(Renderer2); private _element = inject(ElementRef); @@ -39,7 +39,7 @@ export class HlmSheetContentDirective { this._renderer.setAttribute(this._element.nativeElement, 'data-state', this.state()); }); effect(() => { - this._sideProvider?.side(); + this._sideProvider.side(); this._class = this.generateClasses(); }); } @@ -53,6 +53,6 @@ export class HlmSheetContentDirective { } private generateClasses() { - return hlm(sheetVariants({ side: this._sideProvider?.side() }), this._inputs); + return hlm(sheetVariants({ side: this._sideProvider.side() }), this._inputs); } } diff --git a/libs/ui/accordion/brain/src/lib/brn-accordion-content.component.ts b/libs/ui/accordion/brain/src/lib/brn-accordion-content.component.ts index 1948580e8..57f39aa33 100644 --- a/libs/ui/accordion/brain/src/lib/brn-accordion-content.component.ts +++ b/libs/ui/accordion/brain/src/lib/brn-accordion-content.component.ts @@ -3,23 +3,17 @@ import { ChangeDetectionStrategy, Component, ElementRef, - forwardRef, inject, signal, ViewEncapsulation, } from '@angular/core'; -import { CustomElementClassSettable, SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN } from '@spartan-ng/ui-core'; +import { CustomElementClassSettable, provideCustomClassSettableExisting } from '@spartan-ng/ui-core'; import { BrnAccordionItemComponent } from './brn-accordion-item.component'; @Component({ selector: 'brn-accordion-content', standalone: true, - providers: [ - { - provide: SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN, - useExisting: forwardRef(() => BrnAccordionContentComponent), - }, - ], + providers: [provideCustomClassSettableExisting(() => BrnAccordionContentComponent)], host: { '[attr.data-state]': 'state()', '[attr.aria-labelledby]': 'ariaLabeledBy', diff --git a/libs/ui/accordion/brain/src/lib/brn-accordion-trigger.component.ts b/libs/ui/accordion/brain/src/lib/brn-accordion-trigger.component.ts index ee1ab3359..99442c43f 100644 --- a/libs/ui/accordion/brain/src/lib/brn-accordion-trigger.component.ts +++ b/libs/ui/accordion/brain/src/lib/brn-accordion-trigger.component.ts @@ -1,17 +1,12 @@ -import { Component, ElementRef, forwardRef, inject, signal } from '@angular/core'; -import { CustomElementClassSettable, SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN } from '@spartan-ng/ui-core'; +import { Component, ElementRef, inject, signal } from '@angular/core'; +import { CustomElementClassSettable, provideCustomClassSettableExisting } from '@spartan-ng/ui-core'; import { BrnAccordionItemComponent } from './brn-accordion-item.component'; import { BrnAccordionComponent } from './brn-accordion.component'; @Component({ selector: 'brn-accordion-trigger', standalone: true, - providers: [ - { - provide: SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN, - useExisting: forwardRef(() => BrnAccordionTriggerComponent), - }, - ], + providers: [provideCustomClassSettableExisting(() => BrnAccordionTriggerComponent)], host: { '[attr.data-state]': 'state()', '[attr.aria-expanded]': 'state() === "open"', diff --git a/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-content.directive.ts b/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-content.directive.ts index b1c961ffc..616e13834 100644 --- a/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-content.directive.ts +++ b/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-content.directive.ts @@ -1,15 +1,10 @@ -import { Directive, forwardRef } from '@angular/core'; -import { EXPOSES_STATE_TOKEN } from '@spartan-ng/ui-core'; +import { Directive } from '@angular/core'; +import { provideExposesStateProviderExisting } from '@spartan-ng/ui-core'; import { BrnDialogContentDirective } from '@spartan-ng/ui-dialog-brain'; @Directive({ selector: '[brnAlertDialogContent]', standalone: true, - providers: [ - { - provide: EXPOSES_STATE_TOKEN, - useExisting: forwardRef(() => BrnAlertDialogContentDirective), - }, - ], + providers: [provideExposesStateProviderExisting(() => BrnAlertDialogContentDirective)], }) export class BrnAlertDialogContentDirective extends BrnDialogContentDirective {} diff --git a/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-overlay.component.ts b/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-overlay.component.ts index fb30e6409..f8db49a7d 100644 --- a/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-overlay.component.ts +++ b/libs/ui/alert-dialog/brain/src/lib/brn-alert-dialog-overlay.component.ts @@ -1,16 +1,11 @@ -import { ChangeDetectionStrategy, Component, forwardRef, ViewEncapsulation } from '@angular/core'; -import { SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN } from '@spartan-ng/ui-core'; +import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core'; +import { provideCustomClassSettableExisting } from '@spartan-ng/ui-core'; import { BrnDialogOverlayComponent } from '@spartan-ng/ui-dialog-brain'; @Component({ selector: 'brn-alert-dialog-overlay', standalone: true, - providers: [ - { - provide: SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN, - useExisting: forwardRef(() => BrnAlertDialogOverlayComponent), - }, - ], + providers: [provideCustomClassSettableExisting(() => BrnAlertDialogOverlayComponent)], template: ``, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, diff --git a/libs/ui/command/helm/src/lib/hlm-command-dialog.directive.ts b/libs/ui/command/helm/src/lib/hlm-command-dialog.directive.ts index a9967bbe1..9636eb4d0 100644 --- a/libs/ui/command/helm/src/lib/hlm-command-dialog.directive.ts +++ b/libs/ui/command/helm/src/lib/hlm-command-dialog.directive.ts @@ -10,7 +10,7 @@ import { HlmCommandDirective } from './hlm-command.directive'; }) export class HlmCommandDialogDirective { private _stateProvider = injectExposesStateProvider({ host: true }); - public state = this._stateProvider?.state ?? signal('closed').asReadonly(); + public state = this._stateProvider.state ?? signal('closed').asReadonly(); private _renderer = inject(Renderer2); private _element = inject(ElementRef); diff --git a/libs/ui/core/src/lib/brain/create-injection-token.ts b/libs/ui/core/src/lib/brain/create-injection-token.ts new file mode 100644 index 000000000..b777dcda8 --- /dev/null +++ b/libs/ui/core/src/lib/brain/create-injection-token.ts @@ -0,0 +1,40 @@ +import { InjectionToken, Type, forwardRef, inject, type InjectOptions, type Provider } from '@angular/core'; + +type InjectFn = { + (): TTokenValue; + (injectOptions: InjectOptions & { optional?: false }): TTokenValue; + (injectOptions: InjectOptions & { optional: true }): TTokenValue | null; +}; + +type ProvideFn = { + (value: TTokenValue): Provider; +}; + +type ProvideExistingFn = { + (valueFactory: () => Type): Provider; +}; + +export type CreateInjectionTokenReturn = [ + InjectFn, + ProvideFn, + ProvideExistingFn, + InjectionToken, +]; + +export function createInjectionToken(description: string): CreateInjectionTokenReturn { + const token = new InjectionToken(description); + + const provideFn = (value: TTokenValue) => { + return { provide: token, useValue: value }; + }; + + const provideExistingFn = (value: () => TTokenValue) => { + return { provide: token, useExisting: forwardRef(value) }; + }; + + const injectFn = (options: InjectOptions = {}) => { + return inject(token, options); + }; + + return [injectFn, provideFn, provideExistingFn, token] as CreateInjectionTokenReturn; +} diff --git a/libs/ui/core/src/lib/brain/custom-element-class-settable.ts b/libs/ui/core/src/lib/brain/custom-element-class-settable.ts index 0843e0923..e0654081b 100644 --- a/libs/ui/core/src/lib/brain/custom-element-class-settable.ts +++ b/libs/ui/core/src/lib/brain/custom-element-class-settable.ts @@ -1,10 +1,12 @@ -import { inject, InjectionToken, InjectOptions } from '@angular/core'; +import { createInjectionToken } from './create-injection-token'; export interface CustomElementClassSettable { setClassToCustomElement: (newClass: string) => void; } -export const SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN: InjectionToken = - new InjectionToken('@spartan-ng SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN'); - -export const injectCustomClassSettable = (options: InjectOptions) => inject(SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN, options); +export const [ + injectCustomClassSettable, + provideCustomClassSettable, + provideCustomClassSettableExisting, + SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN, +] = createInjectionToken('@spartan-ng SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN'); diff --git a/libs/ui/core/src/lib/brain/exposes-side.ts b/libs/ui/core/src/lib/brain/exposes-side.ts index d8e8e6bea..7be4636fb 100644 --- a/libs/ui/core/src/lib/brain/exposes-side.ts +++ b/libs/ui/core/src/lib/brain/exposes-side.ts @@ -1,11 +1,13 @@ -import { inject, InjectionToken, InjectOptions, Signal } from '@angular/core'; +import type { Signal } from '@angular/core'; +import { createInjectionToken } from './create-injection-token'; export interface ExposesSide { side: Signal<'top' | 'bottom' | 'left' | 'right'>; } -export const EXPOSES_SIDE_TOKEN: InjectionToken = new InjectionToken( - '@spartan-ng EXPOSES_SIDE_TOKEN', -); - -export const injectExposedSideProvider = (options: InjectOptions) => inject(EXPOSES_SIDE_TOKEN, options); +export const [ + injectExposedSideProvider, + provideExposedSideProvider, + provideExposedSideProviderExisting, + EXPOSES_SIDE_TOKEN, +] = createInjectionToken('@spartan-ng EXPOSES_SIDE_TOKEN'); diff --git a/libs/ui/core/src/lib/brain/exposes-state.ts b/libs/ui/core/src/lib/brain/exposes-state.ts index 118fa2fdf..2a3a1e5cf 100644 --- a/libs/ui/core/src/lib/brain/exposes-state.ts +++ b/libs/ui/core/src/lib/brain/exposes-state.ts @@ -1,11 +1,13 @@ -import { inject, InjectionToken, InjectOptions, Signal } from '@angular/core'; +import { Signal } from '@angular/core'; +import { createInjectionToken } from './create-injection-token'; export interface ExposesState { state: Signal<'open' | 'closed'>; } -export const EXPOSES_STATE_TOKEN: InjectionToken = new InjectionToken( - '@spartan-ng EXPOSES_STATE_TOKEN', -); - -export const injectExposesStateProvider = (options: InjectOptions) => inject(EXPOSES_STATE_TOKEN, options); +export const [ + injectExposesStateProvider, + provideExposesStateProvider, + provideExposesStateProviderExisting, + EXPOSES_STATE_TOKEN, +] = createInjectionToken('@spartan-ng EXPOSES_STATE_TOKEN'); diff --git a/libs/ui/core/src/lib/brain/table-classes-settable.ts b/libs/ui/core/src/lib/brain/table-classes-settable.ts index df403f0b7..c58c4e07d 100644 --- a/libs/ui/core/src/lib/brain/table-classes-settable.ts +++ b/libs/ui/core/src/lib/brain/table-classes-settable.ts @@ -1,11 +1,12 @@ -import { inject, InjectionToken, InjectOptions } from '@angular/core'; +import { createInjectionToken } from './create-injection-token'; export interface TableClassesSettable { setTableClasses: (classes: Partial<{ table: string; headerRow: string; bodyRow: string }>) => void; } -export const SET_TABLE_CLASSES_TOKEN: InjectionToken = new InjectionToken( - '@spartan-ng SET_TABLE_CLASSES_TOKEN', -); - -export const injectTableClassesSettable = (options: InjectOptions) => inject(SET_TABLE_CLASSES_TOKEN, options); +export const [ + injectTableClassesSettable, + provideTableClassesSettable, + provideTableClassesSettableExisting, + SET_TABLE_CLASSES_TOKEN, +] = createInjectionToken('@spartan-ng SET_TABLE_CLASSES_TOKEN'); diff --git a/libs/ui/dialog/brain/src/lib/brn-dialog-content.directive.ts b/libs/ui/dialog/brain/src/lib/brn-dialog-content.directive.ts index 1a8fa094d..2a4af414b 100644 --- a/libs/ui/dialog/brain/src/lib/brn-dialog-content.directive.ts +++ b/libs/ui/dialog/brain/src/lib/brn-dialog-content.directive.ts @@ -1,18 +1,13 @@ -import { Directive, forwardRef, inject, Input, TemplateRef } from '@angular/core'; -import { EXPOSES_STATE_TOKEN } from '@spartan-ng/ui-core'; +import { Directive, inject, Input, TemplateRef } from '@angular/core'; +import { ExposesState, provideExposesStateProviderExisting } from '@spartan-ng/ui-core'; import { BrnDialogComponent } from './brn-dialog.component'; @Directive({ selector: '[brnDialogContent]', standalone: true, - providers: [ - { - provide: EXPOSES_STATE_TOKEN, - useExisting: forwardRef(() => BrnDialogContentDirective), - }, - ], + providers: [provideExposesStateProviderExisting(() => BrnDialogContentDirective)], }) -export class BrnDialogContentDirective { +export class BrnDialogContentDirective implements ExposesState { private _brnDialog = inject(BrnDialogComponent); private _template = inject(TemplateRef); public state = this._brnDialog.state; diff --git a/libs/ui/dialog/brain/src/lib/brn-dialog-overlay.component.ts b/libs/ui/dialog/brain/src/lib/brn-dialog-overlay.component.ts index eb16bfc57..f08c0a9b2 100644 --- a/libs/ui/dialog/brain/src/lib/brn-dialog-overlay.component.ts +++ b/libs/ui/dialog/brain/src/lib/brn-dialog-overlay.component.ts @@ -1,21 +1,16 @@ -import { ChangeDetectionStrategy, Component, forwardRef, inject, Input, ViewEncapsulation } from '@angular/core'; -import { SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN } from '@spartan-ng/ui-core'; +import { ChangeDetectionStrategy, Component, inject, Input, ViewEncapsulation } from '@angular/core'; +import { CustomElementClassSettable, provideCustomClassSettableExisting } from '@spartan-ng/ui-core'; import { BrnDialogComponent } from './brn-dialog.component'; @Component({ selector: 'brn-dialog-overlay', standalone: true, - providers: [ - { - provide: SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN, - useExisting: forwardRef(() => BrnDialogOverlayComponent), - }, - ], + providers: [provideCustomClassSettableExisting(() => BrnDialogOverlayComponent)], template: ``, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class BrnDialogOverlayComponent { +export class BrnDialogOverlayComponent implements CustomElementClassSettable { private _brnDialog = inject(BrnDialogComponent); @Input() set class(newClass: string | null | undefined) { diff --git a/libs/ui/dialog/helm/src/lib/hlm-dialog-content.directive.ts b/libs/ui/dialog/helm/src/lib/hlm-dialog-content.directive.ts index f1e9806ce..ca4cd535d 100644 --- a/libs/ui/dialog/helm/src/lib/hlm-dialog-content.directive.ts +++ b/libs/ui/dialog/helm/src/lib/hlm-dialog-content.directive.ts @@ -9,7 +9,7 @@ import { ClassValue } from 'clsx'; export class HlmDialogContentDirective { private _inputs: ClassValue = ''; private _statusProvider = injectExposesStateProvider({ host: true }); - public state = this._statusProvider?.state ?? signal('closed').asReadonly(); + public state = this._statusProvider.state ?? signal('closed').asReadonly(); private _renderer = inject(Renderer2); private _element = inject(ElementRef); diff --git a/libs/ui/hover-card/brain/src/lib/brn-hover-card-content.directive.ts b/libs/ui/hover-card/brain/src/lib/brn-hover-card-content.directive.ts index 8b06f25a9..bf5f07d0a 100644 --- a/libs/ui/hover-card/brain/src/lib/brn-hover-card-content.directive.ts +++ b/libs/ui/hover-card/brain/src/lib/brn-hover-card-content.directive.ts @@ -1,5 +1,10 @@ -import { Directive, forwardRef, inject, TemplateRef } from '@angular/core'; -import { EXPOSES_SIDE_TOKEN, EXPOSES_STATE_TOKEN, ExposesSide, ExposesState } from '@spartan-ng/ui-core'; +import { Directive, inject, TemplateRef } from '@angular/core'; +import { + ExposesSide, + ExposesState, + provideExposedSideProviderExisting, + provideExposesStateProviderExisting, +} from '@spartan-ng/ui-core'; import { BrnHoverCardContentService } from './brn-hover-card-content.service'; @Directive({ @@ -7,14 +12,8 @@ import { BrnHoverCardContentService } from './brn-hover-card-content.service'; standalone: true, exportAs: 'brnHoverCardContent', providers: [ - { - provide: EXPOSES_STATE_TOKEN, - useExisting: forwardRef(() => BrnHoverCardContentDirective), - }, - { - provide: EXPOSES_SIDE_TOKEN, - useExisting: forwardRef(() => BrnHoverCardContentDirective), - }, + provideExposedSideProviderExisting(() => BrnHoverCardContentDirective), + provideExposesStateProviderExisting(() => BrnHoverCardContentDirective), ], }) export class BrnHoverCardContentDirective implements ExposesState, ExposesSide { diff --git a/libs/ui/hover-card/helm/src/lib/hlm-hover-card-content.directive.ts b/libs/ui/hover-card/helm/src/lib/hlm-hover-card-content.directive.ts index 1992667ad..733799fa2 100644 --- a/libs/ui/hover-card/helm/src/lib/hlm-hover-card-content.directive.ts +++ b/libs/ui/hover-card/helm/src/lib/hlm-hover-card-content.directive.ts @@ -11,8 +11,8 @@ export class HlmHoverCardContentDirective { private _inputs: ClassValue = ''; - public readonly state = this._statusProvider?.state ?? signal('closed').asReadonly(); - public readonly side = this._sideProvider?.side ?? signal('bottom').asReadonly(); + public readonly state = this._statusProvider.state ?? signal('closed').asReadonly(); + public readonly side = this._sideProvider.side ?? signal('bottom').asReadonly(); constructor() { effect(() => { diff --git a/libs/ui/popover/brain/src/lib/brn-popover-content.directive.ts b/libs/ui/popover/brain/src/lib/brn-popover-content.directive.ts index 1b18b4e5f..467eaff27 100644 --- a/libs/ui/popover/brain/src/lib/brn-popover-content.directive.ts +++ b/libs/ui/popover/brain/src/lib/brn-popover-content.directive.ts @@ -1,15 +1,10 @@ -import { Directive, forwardRef } from '@angular/core'; -import { EXPOSES_STATE_TOKEN } from '@spartan-ng/ui-core'; +import { Directive } from '@angular/core'; +import { provideExposesStateProviderExisting } from '@spartan-ng/ui-core'; import { BrnDialogContentDirective } from '@spartan-ng/ui-dialog-brain'; @Directive({ selector: '[brnPopoverContent]', standalone: true, - providers: [ - { - provide: EXPOSES_STATE_TOKEN, - useExisting: forwardRef(() => BrnPopoverContentDirective), - }, - ], + providers: [provideExposesStateProviderExisting(() => BrnPopoverContentDirective)], }) export class BrnPopoverContentDirective extends BrnDialogContentDirective {} diff --git a/libs/ui/popover/helm/src/lib/hlm-popover-content.directive.ts b/libs/ui/popover/helm/src/lib/hlm-popover-content.directive.ts index 13fe69822..40ef68024 100644 --- a/libs/ui/popover/helm/src/lib/hlm-popover-content.directive.ts +++ b/libs/ui/popover/helm/src/lib/hlm-popover-content.directive.ts @@ -9,7 +9,7 @@ import { ClassValue } from 'clsx'; export class HlmPopoverContentDirective { private _inputs: ClassValue = ''; private _stateProvider = injectExposesStateProvider({ host: true }); - public state = this._stateProvider?.state ?? signal('closed'); + public state = this._stateProvider.state ?? signal('closed'); private _renderer = inject(Renderer2); private _element = inject(ElementRef); diff --git a/libs/ui/sheet/brain/src/lib/brn-sheet-content.directive.ts b/libs/ui/sheet/brain/src/lib/brn-sheet-content.directive.ts index 47d5d9e7e..76ed4ce36 100644 --- a/libs/ui/sheet/brain/src/lib/brn-sheet-content.directive.ts +++ b/libs/ui/sheet/brain/src/lib/brn-sheet-content.directive.ts @@ -1,5 +1,9 @@ -import { Directive, forwardRef, inject } from '@angular/core'; -import { EXPOSES_SIDE_TOKEN, EXPOSES_STATE_TOKEN } from '@spartan-ng/ui-core'; +import { Directive, inject } from '@angular/core'; +import { + ExposesSide, + provideExposedSideProviderExisting, + provideExposesStateProviderExisting, +} from '@spartan-ng/ui-core'; import { BrnDialogContentDirective } from '@spartan-ng/ui-dialog-brain'; import { BrnSheetComponent } from './brn-sheet.component'; @@ -7,16 +11,10 @@ import { BrnSheetComponent } from './brn-sheet.component'; selector: '[brnSheetContent]', standalone: true, providers: [ - { - provide: EXPOSES_STATE_TOKEN, - useExisting: forwardRef(() => BrnSheetContentDirective), - }, - { - provide: EXPOSES_SIDE_TOKEN, - useExisting: forwardRef(() => BrnSheetContentDirective), - }, + provideExposesStateProviderExisting(() => BrnSheetContentDirective), + provideExposedSideProviderExisting(() => BrnSheetContentDirective), ], }) -export class BrnSheetContentDirective extends BrnDialogContentDirective { +export class BrnSheetContentDirective extends BrnDialogContentDirective implements ExposesSide { public readonly side = inject(BrnSheetComponent).side; } diff --git a/libs/ui/sheet/brain/src/lib/brn-sheet-overlay.component.ts b/libs/ui/sheet/brain/src/lib/brn-sheet-overlay.component.ts index 1c281223a..8637efca1 100644 --- a/libs/ui/sheet/brain/src/lib/brn-sheet-overlay.component.ts +++ b/libs/ui/sheet/brain/src/lib/brn-sheet-overlay.component.ts @@ -1,16 +1,11 @@ -import { ChangeDetectionStrategy, Component, forwardRef, ViewEncapsulation } from '@angular/core'; -import { SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN } from '@spartan-ng/ui-core'; +import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core'; +import { provideCustomClassSettableExisting } from '@spartan-ng/ui-core'; import { BrnDialogOverlayComponent } from '@spartan-ng/ui-dialog-brain'; @Component({ selector: 'brn-sheet-overlay', standalone: true, - providers: [ - { - provide: SET_CLASS_TO_CUSTOM_ELEMENT_TOKEN, - useExisting: forwardRef(() => BrnSheetOverlayComponent), - }, - ], + providers: [provideCustomClassSettableExisting(() => BrnSheetOverlayComponent)], template: ``, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, diff --git a/libs/ui/sheet/helm/src/lib/hlm-sheet-content.directive.ts b/libs/ui/sheet/helm/src/lib/hlm-sheet-content.directive.ts index 171f9620d..ff74fba20 100644 --- a/libs/ui/sheet/helm/src/lib/hlm-sheet-content.directive.ts +++ b/libs/ui/sheet/helm/src/lib/hlm-sheet-content.directive.ts @@ -30,7 +30,7 @@ export class HlmSheetContentDirective { private _inputs: ClassValue = ''; private _stateProvider = injectExposesStateProvider({ host: true }); private _sideProvider = injectExposedSideProvider({ host: true }); - public state = this._stateProvider?.state ?? signal('closed'); + public state = this._stateProvider.state ?? signal('closed'); private _renderer = inject(Renderer2); private _element = inject(ElementRef); @@ -39,7 +39,7 @@ export class HlmSheetContentDirective { this._renderer.setAttribute(this._element.nativeElement, 'data-state', this.state()); }); effect(() => { - this._sideProvider?.side(); + this._sideProvider.side(); this._class = this.generateClasses(); }); } @@ -53,6 +53,6 @@ export class HlmSheetContentDirective { } private generateClasses() { - return hlm(sheetVariants({ side: this._sideProvider?.side() }), this._inputs); + return hlm(sheetVariants({ side: this._sideProvider.side() }), this._inputs); } } diff --git a/libs/ui/table/brain/src/lib/brn-table.component.ts b/libs/ui/table/brain/src/lib/brn-table.component.ts index b79b1c945..e80a2fa0c 100644 --- a/libs/ui/table/brain/src/lib/brn-table.component.ts +++ b/libs/ui/table/brain/src/lib/brn-table.component.ts @@ -13,9 +13,8 @@ import { ViewChild, ViewEncapsulation, booleanAttribute, - forwardRef, } from '@angular/core'; -import { SET_TABLE_CLASSES_TOKEN, TableClassesSettable } from '@spartan-ng/ui-core'; +import { TableClassesSettable, provideTableClassesSettableExisting } from '@spartan-ng/ui-core'; import { BrnColumnDefComponent } from './brn-column-def.component'; export type BrnTableDataSourceInput = CdkTableDataSourceInput; @@ -24,12 +23,7 @@ export type BrnTableDataSourceInput = CdkTableDataSourceInput; selector: 'brn-table', standalone: true, imports: [CdkTableModule, NgIf], - providers: [ - { - provide: SET_TABLE_CLASSES_TOKEN, - useExisting: forwardRef(() => BrnTableComponent), - }, - ], + providers: [provideTableClassesSettableExisting(() => BrnTableComponent)], template: `