Skip to content

Commit 0b782fe

Browse files
committed
refactor(modal): visible signal, cleanup
1 parent 625d3d7 commit 0b782fe

File tree

2 files changed

+25
-30
lines changed

2 files changed

+25
-30
lines changed

projects/coreui-angular/src/lib/modal/modal/modal.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
[scrollable]="scrollable()"
55
[size]="size()">
66
<c-modal-content>
7-
<div [cdkTrapFocus]="visible" [cdkTrapFocusAutoCapture]="visible" style="display: contents;" #modalContentRef>
7+
@let isVisible = visible();
8+
<div [cdkTrapFocus]="isVisible" [cdkTrapFocusAutoCapture]="isVisible" style="display: contents;" #modalContentRef>
89
<ng-content />
910
</div>
1011
</c-modal-content>

projects/coreui-angular/src/lib/modal/modal/modal.component.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { animate, AnimationEvent, state, style, transition, trigger } from '@angular/animations';
22
import { A11yModule, FocusMonitor } from '@angular/cdk/a11y';
3+
import { BooleanInput } from '@angular/cdk/coercion';
34
import {
45
AfterViewInit,
56
booleanAttribute,
@@ -11,14 +12,14 @@ import {
1112
ElementRef,
1213
inject,
1314
input,
15+
linkedSignal,
1416
OnDestroy,
1517
OnInit,
1618
output,
1719
Renderer2,
1820
signal,
1921
untracked,
20-
viewChild,
21-
WritableSignal
22+
viewChild
2223
} from '@angular/core';
2324
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2425

@@ -66,6 +67,10 @@ import { ModalDialogComponent } from '../modal-dialog/modal-dialog.component';
6667
}
6768
})
6869
export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
70+
static ngAcceptInputType_ariaModalInput: BooleanInput;
71+
static ngAcceptInputType_scrollable: BooleanInput;
72+
static ngAcceptInputType_visibleInput: BooleanInput;
73+
6974
readonly #document = inject<Document>(DOCUMENT);
7075
readonly #renderer = inject(Renderer2);
7176
readonly #hostElement = inject(ElementRef);
@@ -136,7 +141,7 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
136141
readonly ariaModalInput = input(false, { transform: booleanAttribute, alias: 'ariaModal' });
137142

138143
readonly ariaModal = computed(() => {
139-
return this.visible || this.ariaModalInput() ? true : null;
144+
return this.visible() || this.ariaModalInput() ? true : null;
140145
});
141146

142147
/**
@@ -153,32 +158,21 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
153158
*/
154159
readonly visibleInput = input(false, { transform: booleanAttribute, alias: 'visible' });
155160

161+
readonly visible = linkedSignal(this.visibleInput);
162+
156163
readonly #visibleInputEffect = effect(() => {
157-
const visible = this.visibleInput();
164+
const visible = this.visible();
158165
untracked(() => {
159-
this.visible = visible;
166+
this.setBodyStyles(visible);
167+
this.setBackdrop(this.backdrop() !== false && visible);
168+
this.visibleChange?.emit(visible);
160169
});
161170
});
162171

163-
set visible(value: boolean) {
164-
if (this.#visible() !== value) {
165-
this.#visible.set(value);
166-
this.setBodyStyles(value);
167-
this.setBackdrop(this.backdrop() !== false && value);
168-
this.visibleChange?.emit(value);
169-
}
170-
}
171-
172-
get visible(): boolean {
173-
return this.#visible();
174-
}
175-
176-
readonly #visible: WritableSignal<boolean> = signal(false);
177-
178172
readonly #activeElement = signal<HTMLElement | null>(null);
179173

180174
readonly #visibleEffect = effect(() => {
181-
const visible = this.#visible();
175+
const visible = this.visible();
182176
const afterViewInit = this.#afterViewInit();
183177
untracked(() => {
184178
if (visible && afterViewInit) {
@@ -229,15 +223,15 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
229223
});
230224

231225
get ariaHidden(): boolean | null {
232-
return this.visible ? null : true;
226+
return this.visible() ? null : true;
233227
}
234228

235229
readonly animateTrigger = computed(() => {
236-
return this.visible ? 'visible' : 'hidden';
230+
return this.visible() ? 'visible' : 'hidden';
237231
});
238232

239233
get show(): boolean {
240-
return this.visible && this.#show();
234+
return this.visible() && this.#show();
241235
}
242236

243237
set show(value: boolean) {
@@ -264,11 +258,11 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
264258
this.#backdropService.resetScrollbar();
265259
}
266260
});
267-
this.show = this.visible;
261+
this.show = this.visible();
268262
}
269263

270264
onKeyUpHandler(event: KeyboardEvent): void {
271-
if (event.key === 'Escape' && this.keyboard() && this.visible) {
265+
if (event.key === 'Escape' && this.keyboard() && this.visible()) {
272266
if (this.backdrop() === 'static') {
273267
this.setStaticBackdrop();
274268
} else {
@@ -319,11 +313,11 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
319313
this.#modalService.modalState$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((action) => {
320314
if (this === action.modal || this.id === action.id) {
321315
if ('show' in action) {
322-
this.visible = action?.show === 'toggle' ? !this.visible : action.show;
316+
this.visible.update((visible) => (action?.show === 'toggle' ? !visible : action.show));
323317
}
324318
} else {
325-
if (this.visible) {
326-
this.visible = false;
319+
if (this.visible()) {
320+
this.visible.set(false);
327321
}
328322
}
329323
});

0 commit comments

Comments
 (0)