Skip to content

Commit

Permalink
feat(cdk): DirectiveBinding / DirectiveListener add utils
Browse files Browse the repository at this point in the history
Signed-off-by: waterplea <[email protected]>
  • Loading branch information
waterplea authored and splincode committed Jun 3, 2024
1 parent 1c83424 commit 7131c2f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 1 deletion.
26 changes: 26 additions & 0 deletions projects/cdk/utils/miscellaneous/directive-binding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type {ProviderToken, WritableSignal} from '@angular/core';
import {effect, inject, isSignal, signal} from '@angular/core';

export function tuiDirectiveBinding<T, G extends keyof T, R>(
token: ProviderToken<T>,
key: G,
initial: T[G] extends WritableSignal<R> ? R : T[G],
): WritableSignal<typeof initial> {
const result = signal(initial);
const directive = inject(token);

effect(
() => {
const value: any = result();

if (isSignal(directive[key])) {
(directive[key] as WritableSignal<T[G]>).set(value);
} else {
directive[key] = value;
}
},
{allowSignalWrites: true},
);

return result;
}
20 changes: 20 additions & 0 deletions projects/cdk/utils/miscellaneous/directive-listener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type {ProviderToken, Signal} from '@angular/core';
import {inject, isSignal} from '@angular/core';
import {toSignal} from '@angular/core/rxjs-interop';
import type {Observable} from 'rxjs';

type OutputKeysOf<T> = {
[K in keyof T]: T[K] extends Observable<any> | Signal<any> ? K : never;
}[keyof T];

type OutputTypeOf<T> =
T extends Signal<infer R> ? R : T extends Observable<infer O> ? O : never;

export function tuiDirectiveListener<T, K extends OutputKeysOf<T>>(
token: ProviderToken<T>,
key: K,
): Signal<OutputTypeOf<T[K]>> {
const prop: any = inject(token)[key];

return isSignal(prop) ? prop : toSignal<any>(prop);
}
2 changes: 2 additions & 0 deletions projects/cdk/utils/miscellaneous/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export * from './clean-object';
export * from './create-options';
export * from './create-token';
export * from './default-sort';
export * from './directive-binding';
export * from './directive-listener';
export * from './distance-between-touches';
export * from './ease-in-out-quad';
export * from './flat-length';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export class TuiHintAsideDirective implements DoCheck {
private readonly aside = inject(TuiAsideComponent);
private readonly hint = inject(TuiHintDirective);

// TODO: switch to `tuiDirectiveBinding` when tuiNavigationAside is switched to signal
public ngDoCheck(): void {
this.hint.tuiHint = this.aside.tuiNavigationAside
? ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class TuiInputFilesDirective
public readonly reject = timer(0).pipe(
switchMap(() => tuiControlValue(this.control)),
map(() => tuiFilesRejected(this.control)),
filter(rejected => !!rejected.length),
filter(({length}) => !!length),
);

public readonly appearance = 'file';
Expand Down

0 comments on commit 7131c2f

Please sign in to comment.