@mesgflow/ui-kit 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -5
- package/fesm2022/mesgflow-ui-kit-accordion.mjs +9 -8
- package/fesm2022/mesgflow-ui-kit-accordion.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-agenda.mjs +208 -0
- package/fesm2022/mesgflow-ui-kit-agenda.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-alert.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-aspect-ratio.mjs +37 -0
- package/fesm2022/mesgflow-ui-kit-aspect-ratio.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-avatar-group.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-avatar.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-badge.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-banner.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-blocks.mjs +207 -0
- package/fesm2022/mesgflow-ui-kit-blocks.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-box-input.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-box-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-brand.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-breadcrumb.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-button-group.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-button.mjs +190 -244
- package/fesm2022/mesgflow-ui-kit-button.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-card.mjs +48 -27
- package/fesm2022/mesgflow-ui-kit-card.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-carousel.mjs +308 -0
- package/fesm2022/mesgflow-ui-kit-carousel.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-chart.mjs +12 -12
- package/fesm2022/mesgflow-ui-kit-checkbox.mjs +18 -23
- package/fesm2022/mesgflow-ui-kit-checkbox.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-chip.mjs +5 -5
- package/fesm2022/mesgflow-ui-kit-chip.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-code-block.mjs +11 -7
- package/fesm2022/mesgflow-ui-kit-code-block.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-collapsible.mjs +9 -9
- package/fesm2022/mesgflow-ui-kit-color-picker.mjs +9 -7
- package/fesm2022/mesgflow-ui-kit-color-picker.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-combobox.mjs +147 -67
- package/fesm2022/mesgflow-ui-kit-combobox.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-command.mjs +15 -16
- package/fesm2022/mesgflow-ui-kit-command.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-context-menu.mjs +7 -9
- package/fesm2022/mesgflow-ui-kit-context-menu.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-copy-button.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-core.mjs +446 -128
- package/fesm2022/mesgflow-ui-kit-core.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-countdown.mjs +149 -0
- package/fesm2022/mesgflow-ui-kit-countdown.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-date-picker.mjs +140 -19
- package/fesm2022/mesgflow-ui-kit-date-picker.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-description-list.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-dialog.mjs +310 -64
- package/fesm2022/mesgflow-ui-kit-dialog.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-divider.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-drawer.mjs +109 -0
- package/fesm2022/mesgflow-ui-kit-drawer.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-dropzone.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-dropzone.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-empty-state.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-field.mjs +55 -14
- package/fesm2022/mesgflow-ui-kit-field.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-file-upload.mjs +356 -0
- package/fesm2022/mesgflow-ui-kit-file-upload.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-hover-card.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs +135 -0
- package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-icon.mjs +8 -3
- package/fesm2022/mesgflow-ui-kit-icon.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-icons-lucide.mjs +371 -0
- package/fesm2022/mesgflow-ui-kit-icons-lucide.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-inline-edit.mjs +279 -0
- package/fesm2022/mesgflow-ui-kit-inline-edit.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-input.mjs +162 -19
- package/fesm2022/mesgflow-ui-kit-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-kbd.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-lightbox.mjs +299 -0
- package/fesm2022/mesgflow-ui-kit-lightbox.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-link.mjs +5 -5
- package/fesm2022/mesgflow-ui-kit-link.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-listbox.mjs +151 -0
- package/fesm2022/mesgflow-ui-kit-listbox.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-mention.mjs +283 -0
- package/fesm2022/mesgflow-ui-kit-mention.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-menu.mjs +178 -14
- package/fesm2022/mesgflow-ui-kit-menu.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-nav-menu.mjs +276 -0
- package/fesm2022/mesgflow-ui-kit-nav-menu.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-notification-center.mjs +281 -0
- package/fesm2022/mesgflow-ui-kit-notification-center.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-number-input.mjs +9 -6
- package/fesm2022/mesgflow-ui-kit-number-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-otp-input.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-page-header.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-pagination.mjs +7 -6
- package/fesm2022/mesgflow-ui-kit-pagination.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-password-input.mjs +38 -68
- package/fesm2022/mesgflow-ui-kit-password-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-popover.mjs +12 -52
- package/fesm2022/mesgflow-ui-kit-popover.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-progress.mjs +164 -23
- package/fesm2022/mesgflow-ui-kit-progress.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-qr-code.mjs +766 -0
- package/fesm2022/mesgflow-ui-kit-qr-code.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-radio.mjs +10 -12
- package/fesm2022/mesgflow-ui-kit-radio.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-rating.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-rating.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-scroll-area.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-search-input.mjs +11 -7
- package/fesm2022/mesgflow-ui-kit-search-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-segmented-control.mjs +15 -11
- package/fesm2022/mesgflow-ui-kit-segmented-control.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-select.mjs +6 -5
- package/fesm2022/mesgflow-ui-kit-select.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-sidebar.mjs +24 -21
- package/fesm2022/mesgflow-ui-kit-sidebar.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-skeleton.mjs +6 -5
- package/fesm2022/mesgflow-ui-kit-skeleton.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-slider.mjs +253 -6
- package/fesm2022/mesgflow-ui-kit-slider.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-sortable.mjs +526 -0
- package/fesm2022/mesgflow-ui-kit-sortable.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-spinner.mjs +44 -15
- package/fesm2022/mesgflow-ui-kit-spinner.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-split-button.mjs +205 -0
- package/fesm2022/mesgflow-ui-kit-split-button.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-splitter.mjs +213 -6
- package/fesm2022/mesgflow-ui-kit-splitter.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-stat-tile.mjs +13 -6
- package/fesm2022/mesgflow-ui-kit-stat-tile.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-stepper.mjs +171 -64
- package/fesm2022/mesgflow-ui-kit-stepper.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-switch.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-switch.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-table.mjs +34 -28
- package/fesm2022/mesgflow-ui-kit-table.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tabs.mjs +421 -180
- package/fesm2022/mesgflow-ui-kit-tabs.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tag-input.mjs +9 -4
- package/fesm2022/mesgflow-ui-kit-tag-input.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-theme-switcher.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-theming.mjs +7 -7
- package/fesm2022/mesgflow-ui-kit-theming.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-time-picker.mjs +6 -6
- package/fesm2022/mesgflow-ui-kit-time-picker.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-timeline.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-toast.mjs +118 -35
- package/fesm2022/mesgflow-ui-kit-toast.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-toggle.mjs +12 -11
- package/fesm2022/mesgflow-ui-kit-toggle.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-toolbar.mjs +13 -11
- package/fesm2022/mesgflow-ui-kit-toolbar.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tooltip.mjs +76 -53
- package/fesm2022/mesgflow-ui-kit-tooltip.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-tour.mjs +17 -29
- package/fesm2022/mesgflow-ui-kit-tour.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-transfer-list.mjs +288 -0
- package/fesm2022/mesgflow-ui-kit-transfer-list.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tree-select.mjs +3 -3
- package/fesm2022/mesgflow-ui-kit-tree.mjs +4 -4
- package/fesm2022/mesgflow-ui-kit-tree.mjs.map +1 -1
- package/fesm2022/mesgflow-ui-kit-virtual-list.mjs +109 -0
- package/fesm2022/mesgflow-ui-kit-virtual-list.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit.mjs +93 -12836
- package/fesm2022/mesgflow-ui-kit.mjs.map +1 -1
- package/package.json +91 -3
- package/schematics/collection.json +10 -0
- package/schematics/migration.json +10 -0
- package/schematics/migrations/v0-7.cjs +70 -0
- package/schematics/ng-add/index.cjs +234 -0
- package/schematics/ng-add/schema.json +43 -0
- package/tokens/color.css +96 -0
- package/tokens/controls.css +145 -0
- package/tokens/elevation.css +62 -6
- package/tokens/motion.css +304 -66
- package/tokens/radius.css +14 -0
- package/tokens.css +1 -0
- package/tokens.json +1583 -0
- package/types/mesgflow-ui-kit-agenda.d.ts +49 -0
- package/types/mesgflow-ui-kit-aspect-ratio.d.ts +18 -0
- package/types/mesgflow-ui-kit-blocks.d.ts +128 -0
- package/types/mesgflow-ui-kit-button.d.ts +23 -38
- package/types/mesgflow-ui-kit-card.d.ts +26 -16
- package/types/mesgflow-ui-kit-carousel.d.ts +51 -0
- package/types/mesgflow-ui-kit-checkbox.d.ts +8 -5
- package/types/mesgflow-ui-kit-code-block.d.ts +4 -1
- package/types/mesgflow-ui-kit-combobox.d.ts +47 -22
- package/types/mesgflow-ui-kit-command.d.ts +2 -2
- package/types/mesgflow-ui-kit-core.d.ts +279 -21
- package/types/mesgflow-ui-kit-countdown.d.ts +47 -0
- package/types/mesgflow-ui-kit-date-picker.d.ts +31 -1
- package/types/mesgflow-ui-kit-dialog.d.ts +122 -14
- package/types/mesgflow-ui-kit-drawer.d.ts +45 -0
- package/types/mesgflow-ui-kit-field.d.ts +17 -8
- package/types/mesgflow-ui-kit-file-upload.d.ts +64 -0
- package/types/mesgflow-ui-kit-hover-card.d.ts +2 -2
- package/types/mesgflow-ui-kit-icons-lucide.d.ts +27 -0
- package/types/mesgflow-ui-kit-inline-edit.d.ts +42 -0
- package/types/mesgflow-ui-kit-input.d.ts +64 -2
- package/types/mesgflow-ui-kit-lightbox.d.ts +54 -0
- package/types/mesgflow-ui-kit-listbox.d.ts +30 -0
- package/types/mesgflow-ui-kit-mention.d.ts +59 -0
- package/types/mesgflow-ui-kit-menu.d.ts +41 -2
- package/types/mesgflow-ui-kit-nav-menu.d.ts +58 -0
- package/types/mesgflow-ui-kit-notification-center.d.ts +41 -0
- package/types/mesgflow-ui-kit-number-input.d.ts +3 -1
- package/types/mesgflow-ui-kit-password-input.d.ts +35 -5
- package/types/mesgflow-ui-kit-popover.d.ts +13 -5
- package/types/mesgflow-ui-kit-progress.d.ts +33 -12
- package/types/mesgflow-ui-kit-qr-code.d.ts +160 -0
- package/types/mesgflow-ui-kit-radio.d.ts +2 -2
- package/types/mesgflow-ui-kit-search-input.d.ts +3 -1
- package/types/mesgflow-ui-kit-segmented-control.d.ts +4 -0
- package/types/mesgflow-ui-kit-sidebar.d.ts +1 -1
- package/types/mesgflow-ui-kit-slider.d.ts +60 -1
- package/types/mesgflow-ui-kit-sortable.d.ts +103 -0
- package/types/mesgflow-ui-kit-spinner.d.ts +5 -8
- package/types/mesgflow-ui-kit-split-button.d.ts +47 -0
- package/types/mesgflow-ui-kit-splitter.d.ts +64 -1
- package/types/mesgflow-ui-kit-stat-tile.d.ts +3 -0
- package/types/mesgflow-ui-kit-stepper.d.ts +54 -32
- package/types/mesgflow-ui-kit-table.d.ts +2 -0
- package/types/mesgflow-ui-kit-tabs.d.ts +193 -93
- package/types/mesgflow-ui-kit-tag-input.d.ts +3 -1
- package/types/mesgflow-ui-kit-toast.d.ts +48 -22
- package/types/mesgflow-ui-kit-tooltip.d.ts +15 -12
- package/types/mesgflow-ui-kit-transfer-list.d.ts +34 -0
- package/types/mesgflow-ui-kit-virtual-list.d.ts +35 -0
- package/types/mesgflow-ui-kit.d.ts +88 -5444
|
@@ -1,15 +1,119 @@
|
|
|
1
|
-
import { DIALOG_DATA, DialogRef, Dialog as Dialog$1 } from '@angular/cdk/dialog';
|
|
2
1
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { signal, inject, ElementRef, input,
|
|
2
|
+
import { signal, computed, inject, ElementRef, input, Directive, booleanAttribute, output, viewChild, effect, DestroyRef, afterNextRender, Component, Injector, Injectable } from '@angular/core';
|
|
4
3
|
import { Button } from '@mesgflow/ui-kit/button';
|
|
5
|
-
import { glassSurface, MF_DIALOG_LABELS, cn } from '@mesgflow/ui-kit/core';
|
|
4
|
+
import { glassSurface, MF_DIALOG_LABELS, nextId, cn, exitDurationMs } from '@mesgflow/ui-kit/core';
|
|
6
5
|
import { Icon } from '@mesgflow/ui-kit/icon';
|
|
6
|
+
import { DIALOG_DATA, DialogRef, Dialog as Dialog$1 } from '@angular/cdk/dialog';
|
|
7
7
|
import * as i1 from '@angular/cdk/drag-drop';
|
|
8
8
|
import { CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
|
|
9
9
|
import { cva } from 'class-variance-authority';
|
|
10
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
10
11
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
11
12
|
import { createGlobalPositionStrategy } from '@angular/cdk/overlay';
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* `DialogService.open()`/`openDrawer()`'ın döndürdüğü, kite ait dialog referansı.
|
|
16
|
+
*
|
|
17
|
+
* CDK `DialogRef`'in günlük kullanılan yüzeyini (`close`, `closed`,
|
|
18
|
+
* `componentInstance`, `disableClose`, `backdropClick`, `keydownEvents` …)
|
|
19
|
+
* birebir DELEGE eder — yani eski `ref.closed.subscribe(...)` kodu aynen derlenir.
|
|
20
|
+
* Üstüne kitin kendi dünyasını ekler:
|
|
21
|
+
*
|
|
22
|
+
* - `afterClosed()` — `await` edilebilir sonuç (çıkış animasyonu BİTTİKTEN sonra çözülür).
|
|
23
|
+
* - `state` — `'open' | 'closing' | 'closed'` signal'i (şablonda/`computed`'ta okunur).
|
|
24
|
+
* - `surface` — boyut/maximize/kirli-form durumuna tipli erişim (`setSize`, `toggleMaximize`,
|
|
25
|
+
* `registerDirty`, `markClean` kısayolları).
|
|
26
|
+
* - `cdk` — ham CDK referansı (kaçış kapısı; ör. `updatePosition()`).
|
|
27
|
+
*
|
|
28
|
+
* `close()` İDEMPOTENT'tir: çıkış animasyonu sürerken ya da kirli-form onayı
|
|
29
|
+
* açıkken gelen ek çağrılar yok sayılır (bkz. `dialog.service.ts` `closePredicate`).
|
|
30
|
+
*
|
|
31
|
+
* İçerik component'i içinde `injectDialogRef<Sonuç>()` ile alınır.
|
|
32
|
+
*/
|
|
33
|
+
class MfDialogRef {
|
|
34
|
+
cdk;
|
|
35
|
+
surface;
|
|
36
|
+
closed;
|
|
37
|
+
backdropClick;
|
|
38
|
+
keydownEvents;
|
|
39
|
+
outsidePointerEvents;
|
|
40
|
+
overlayRef;
|
|
41
|
+
id;
|
|
42
|
+
isClosed = signal(false, /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "isClosed" }] : /* istanbul ignore next */ []));
|
|
44
|
+
result;
|
|
45
|
+
/** Dialog'un yaşam döngüsü — `closing` çıkış animasyonu boyunca. */
|
|
46
|
+
state;
|
|
47
|
+
constructor(cdk, surface) {
|
|
48
|
+
this.cdk = cdk;
|
|
49
|
+
this.surface = surface;
|
|
50
|
+
this.closed = cdk.closed;
|
|
51
|
+
this.backdropClick = cdk.backdropClick;
|
|
52
|
+
this.keydownEvents = cdk.keydownEvents;
|
|
53
|
+
this.outsidePointerEvents = cdk.outsidePointerEvents;
|
|
54
|
+
this.overlayRef = cdk.overlayRef;
|
|
55
|
+
this.id = cdk.id;
|
|
56
|
+
this.state = computed(() => this.isClosed() ? 'closed' : surface.closing() ? 'closing' : 'open', /* @ts-ignore */
|
|
57
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
58
|
+
this.result = new Promise((resolve) => cdk.closed.subscribe((value) => {
|
|
59
|
+
this.isClosed.set(true);
|
|
60
|
+
resolve(value);
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
/** Açılan component örneği (şablonla açıldıysa ve kapandıktan sonra `null`). */
|
|
64
|
+
get componentInstance() {
|
|
65
|
+
return this.cdk.componentInstance;
|
|
66
|
+
}
|
|
67
|
+
get componentRef() {
|
|
68
|
+
return this.cdk.componentRef;
|
|
69
|
+
}
|
|
70
|
+
/** `true` iken ESC/backdrop kapatmaz; programatik `close()` yine çalışır. */
|
|
71
|
+
get disableClose() {
|
|
72
|
+
return this.cdk.disableClose;
|
|
73
|
+
}
|
|
74
|
+
set disableClose(value) {
|
|
75
|
+
this.cdk.disableClose = value;
|
|
76
|
+
}
|
|
77
|
+
/** Dialog'u (çıkış animasyonu + kirli-form koruması üzerinden) kapatır. İdempotent. */
|
|
78
|
+
close(result) {
|
|
79
|
+
if (this.isClosed())
|
|
80
|
+
return;
|
|
81
|
+
this.cdk.close(result);
|
|
82
|
+
}
|
|
83
|
+
/** Kapanış tamamlandığında (animasyon dahil) sonuçla çözülür; ESC/backdrop'ta `undefined`. */
|
|
84
|
+
afterClosed() {
|
|
85
|
+
return this.result;
|
|
86
|
+
}
|
|
87
|
+
/** Açıkken genişlik basamağını değiştirir (`sm`…`xl`, `full`). */
|
|
88
|
+
setSize(size) {
|
|
89
|
+
this.surface.size.set(size);
|
|
90
|
+
}
|
|
91
|
+
toggleMaximize() {
|
|
92
|
+
this.surface.toggleMaximize();
|
|
93
|
+
}
|
|
94
|
+
/** Kirli-form sorusunu kaydeder — ESC/backdrop/X kapanışında `true` dönerse onay sorulur. */
|
|
95
|
+
registerDirty(check) {
|
|
96
|
+
this.surface.registerDirty(check);
|
|
97
|
+
}
|
|
98
|
+
/** Başarılı kayıttan hemen önce — sonraki `close()` kirli-form onayı sormaz. */
|
|
99
|
+
markClean() {
|
|
100
|
+
this.surface.markClean();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* `DIALOG_DATA`'nın kite ait adı — AYNI token nesnesi, CDK'dan ayrıca import
|
|
105
|
+
* etmeye gerek kalmasın diye. `inject(MF_DIALOG_DATA)` ≡ `injectDialogData()`.
|
|
106
|
+
*/
|
|
107
|
+
const MF_DIALOG_DATA = DIALOG_DATA;
|
|
108
|
+
/** İçerik component'inde `DialogService.open(..., { data })` ile geçilen veriyi okur. */
|
|
109
|
+
function injectDialogData() {
|
|
110
|
+
return inject(DIALOG_DATA);
|
|
111
|
+
}
|
|
112
|
+
/** İçerik component'inde kendi dialog referansını alır — `ref.close(sonuç)`. */
|
|
113
|
+
function injectDialogRef() {
|
|
114
|
+
return inject(MfDialogRef);
|
|
115
|
+
}
|
|
116
|
+
|
|
13
117
|
/**
|
|
14
118
|
* Dialog başına TEK instance — `DialogService.open()` her açılışta yeni bir
|
|
15
119
|
* tane üretip `options`'tan doldurur, CDK `DialogConfig.providers` ile o
|
|
@@ -30,6 +134,9 @@ class DialogSurface {
|
|
|
30
134
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
31
135
|
placement = signal('center', /* @ts-ignore */
|
|
32
136
|
...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
|
|
137
|
+
/** Çekmecenin fiziksel kenarı (`center`'da `null`) — `DialogService` yön bilgisiyle çözer. */
|
|
138
|
+
side = signal(null, /* @ts-ignore */
|
|
139
|
+
...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
|
|
33
140
|
maximizable = signal(false, /* @ts-ignore */
|
|
34
141
|
...(ngDevMode ? [{ debugName: "maximizable" }] : /* istanbul ignore next */ []));
|
|
35
142
|
draggable = signal(false, /* @ts-ignore */
|
|
@@ -158,10 +265,10 @@ class DialogResizeHandle {
|
|
|
158
265
|
height: Math.min(Math.max(height, MIN_HEIGHT), maxHeight),
|
|
159
266
|
});
|
|
160
267
|
}
|
|
161
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
162
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.
|
|
268
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DialogResizeHandle, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
269
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: DialogResizeHandle, isStandalone: true, selector: "[mfDialogResizeHandle]", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "role": "slider", "tabindex": "0" }, listeners: { "pointerdown": "onPointerDown($event)", "pointermove": "onPointerMove($event)", "pointerup": "onPointerUp($event)", "pointercancel": "onPointerUp($event)", "keydown": "onKeydown($event)" }, properties: { "attr.aria-label": "ariaLabel()", "attr.aria-valuenow": "ariaValueNow()" } }, ngImport: i0 });
|
|
163
270
|
}
|
|
164
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
271
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DialogResizeHandle, decorators: [{
|
|
165
272
|
type: Directive,
|
|
166
273
|
args: [{
|
|
167
274
|
selector: '[mfDialogResizeHandle]',
|
|
@@ -238,16 +345,52 @@ const dialogVariants = cva(`relative flex w-full flex-col overflow-hidden border
|
|
|
238
345
|
normal: 'rounded-xl max-h-[85vh]',
|
|
239
346
|
maximized: 'h-[100dvh] max-h-none w-screen max-w-none rounded-none supports-[backdrop-filter]:bg-surface supports-[backdrop-filter]:backdrop-blur-none',
|
|
240
347
|
sheet: 'w-screen rounded-t-xl rounded-b-none max-h-[92dvh]',
|
|
241
|
-
drawer: '
|
|
348
|
+
drawer: 'max-h-none',
|
|
349
|
+
},
|
|
350
|
+
/** Çekmecenin fiziksel kenarı — yalnızca `state: 'drawer'` ile anlamlı. */
|
|
351
|
+
side: {
|
|
352
|
+
none: '',
|
|
353
|
+
right: '',
|
|
354
|
+
left: '',
|
|
355
|
+
top: '',
|
|
356
|
+
bottom: '',
|
|
242
357
|
},
|
|
243
358
|
},
|
|
244
359
|
compoundVariants: [
|
|
245
|
-
|
|
246
|
-
{ state: 'drawer',
|
|
247
|
-
{ state: 'drawer',
|
|
248
|
-
{ state: 'drawer',
|
|
360
|
+
// Yan çekmeceler: tam yükseklik, boyut ölçeği GENİŞLİK olarak.
|
|
361
|
+
{ state: 'drawer', side: ['left', 'right'], class: 'h-[100dvh]' },
|
|
362
|
+
{ state: 'drawer', side: 'right', class: 'rounded-l-xl rounded-r-none' },
|
|
363
|
+
{ state: 'drawer', side: 'left', class: 'rounded-r-xl rounded-l-none' },
|
|
364
|
+
{
|
|
365
|
+
state: 'drawer',
|
|
366
|
+
side: ['left', 'right'],
|
|
367
|
+
size: 'sm',
|
|
368
|
+
class: 'w-[min(440px,calc(100vw-2rem))]',
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
state: 'drawer',
|
|
372
|
+
side: ['left', 'right'],
|
|
373
|
+
size: 'md',
|
|
374
|
+
class: 'w-[min(560px,calc(100vw-2rem))]',
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
state: 'drawer',
|
|
378
|
+
side: ['left', 'right'],
|
|
379
|
+
size: 'lg',
|
|
380
|
+
class: 'w-[min(720px,calc(100vw-2rem))]',
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
state: 'drawer',
|
|
384
|
+
side: ['left', 'right'],
|
|
385
|
+
size: 'xl',
|
|
386
|
+
class: 'w-[min(960px,calc(100vw-2rem))]',
|
|
387
|
+
},
|
|
388
|
+
// Üst/alt paneller: tam genişlik, içerik yüksekliğinde (en çok %85).
|
|
389
|
+
{ state: 'drawer', side: ['top', 'bottom'], class: 'w-screen max-w-none max-h-[85dvh]' },
|
|
390
|
+
{ state: 'drawer', side: 'top', class: 'rounded-b-xl rounded-t-none' },
|
|
391
|
+
{ state: 'drawer', side: 'bottom', class: 'rounded-t-xl rounded-b-none' },
|
|
249
392
|
],
|
|
250
|
-
defaultVariants: { size: 'md', state: 'normal' },
|
|
393
|
+
defaultVariants: { size: 'md', state: 'normal', side: 'none' },
|
|
251
394
|
});
|
|
252
395
|
|
|
253
396
|
const DRAG_MIN_VISIBLE = 48;
|
|
@@ -288,12 +431,23 @@ class Dialog {
|
|
|
288
431
|
*/
|
|
289
432
|
fillBody = input(false, /* @ts-ignore */
|
|
290
433
|
...(ngDevMode ? [{ debugName: "fillBody" }] : /* istanbul ignore next */ []));
|
|
434
|
+
/**
|
|
435
|
+
* `true` (varsayılan): kapat (X) düğmesi `close` olayını yayınladıktan SONRA
|
|
436
|
+
* dialog'u kendisi de kapatır (`MfDialogRef.close()` — idempotent, tüketicinin
|
|
437
|
+
* `(close)` handler'ında sonuçla yaptığı kapanış önce davranır ve kazanır).
|
|
438
|
+
* `false`: yalnızca `close` yayınlanır — kapanışı tamamen tüketici yönetir.
|
|
439
|
+
*/
|
|
440
|
+
autoClose = input(true, { ...(ngDevMode ? { debugName: "autoClose" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
291
441
|
// `close` adı native DOM `close` olayıyla çakışıyor (@angular-eslint/no-output-native);
|
|
292
442
|
// mevcut public API — yeniden adlandırma kırıcı, ileri bir sürümde ele alınacak.
|
|
293
443
|
// eslint-disable-next-line @angular-eslint/no-output-native
|
|
294
444
|
close = output();
|
|
295
445
|
surface = inject(DialogSurface);
|
|
296
446
|
labels = inject(MF_DIALOG_LABELS);
|
|
447
|
+
/** Görünür başlığın id'si — CDK konteynerinin `aria-labelledby`'ı buna bağlanır. */
|
|
448
|
+
titleId = nextId('mf-dialog-title');
|
|
449
|
+
mfRef = inject(MfDialogRef, { optional: true });
|
|
450
|
+
cdkRef = inject(DialogRef, { optional: true });
|
|
297
451
|
elementRef = inject(ElementRef);
|
|
298
452
|
cdkDrag = inject(CdkDrag, { self: true });
|
|
299
453
|
scrollBody = viewChild('scrollBody', /* @ts-ignore */
|
|
@@ -307,7 +461,7 @@ class Dialog {
|
|
|
307
461
|
return 'sheet';
|
|
308
462
|
if (this.surface.maximized() || this.size() === 'full')
|
|
309
463
|
return 'maximized';
|
|
310
|
-
if (this.surface.
|
|
464
|
+
if (this.surface.side())
|
|
311
465
|
return 'drawer';
|
|
312
466
|
return 'normal';
|
|
313
467
|
}, /* @ts-ignore */
|
|
@@ -322,8 +476,18 @@ class Dialog {
|
|
|
322
476
|
hostClasses = computed(() => {
|
|
323
477
|
const closing = this.surface.closing();
|
|
324
478
|
const state = this.stateVariant();
|
|
325
|
-
const
|
|
326
|
-
|
|
479
|
+
const side = state === 'drawer' ? (this.surface.side() ?? 'right') : null;
|
|
480
|
+
// Kenar başına FİZİKSEL kayma (host `--mf-dir: 1` sabitler — bkz. host bağlaması).
|
|
481
|
+
const animateBase = state === 'sheet' || side === 'bottom'
|
|
482
|
+
? 'sheet'
|
|
483
|
+
: side === 'right'
|
|
484
|
+
? 'drawer'
|
|
485
|
+
: side === 'left'
|
|
486
|
+
? 'drawer-start'
|
|
487
|
+
: side === 'top'
|
|
488
|
+
? 'drawer-top'
|
|
489
|
+
: 'dialog';
|
|
490
|
+
return cn(dialogVariants({ size: this.size() ?? this.surface.size(), state, side: side ?? 'none' }), state === 'normal' && this.surface.customSize() ? 'max-w-none max-h-none' : '', `animate-${animateBase}-${closing ? 'out' : 'in'}`);
|
|
327
491
|
}, /* @ts-ignore */
|
|
328
492
|
...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
329
493
|
customWidth = computed(() => this.stateVariant() === 'normal' ? this.surface.customSize()?.width : undefined, /* @ts-ignore */
|
|
@@ -355,6 +519,17 @@ class Dialog {
|
|
|
355
519
|
this.surface.customSize.set(null);
|
|
356
520
|
}
|
|
357
521
|
});
|
|
522
|
+
// Erişilebilir ad: `ariaLabel` verilmemiş bir dialog'da CDK konteyneri görünür
|
|
523
|
+
// başlığa `aria-labelledby` ile bağlanır (MatDialogTitle'ın kullandığı AYNI kanca).
|
|
524
|
+
// Başlık sonradan boşalırsa/değişirse effect cleanup'ı kaydı geri alır.
|
|
525
|
+
effect((onCleanup) => {
|
|
526
|
+
// `DialogRef.containerInstance` tipi bu (CdkDialogContainer'a ait) metotları taşımıyor.
|
|
527
|
+
const container = this.cdkRef?.containerInstance;
|
|
528
|
+
if (!this.title() || !container?._addAriaLabelledBy)
|
|
529
|
+
return;
|
|
530
|
+
container._addAriaLabelledBy(this.titleId);
|
|
531
|
+
onCleanup(() => container._removeAriaLabelledBy?.(this.titleId));
|
|
532
|
+
});
|
|
358
533
|
const destroyRef = inject(DestroyRef);
|
|
359
534
|
afterNextRender(() => {
|
|
360
535
|
this.updateScrollShadow();
|
|
@@ -366,6 +541,12 @@ class Dialog {
|
|
|
366
541
|
destroyRef.onDestroy(() => observer.disconnect());
|
|
367
542
|
});
|
|
368
543
|
}
|
|
544
|
+
/** Kapat (X): önce `close` olayı (tüketici sonuçla kapatabilsin), sonra — `autoClose` ise — ref'in kendisi. */
|
|
545
|
+
onDismiss() {
|
|
546
|
+
this.close.emit();
|
|
547
|
+
if (this.autoClose())
|
|
548
|
+
(this.mfRef ?? this.cdkRef)?.close();
|
|
549
|
+
}
|
|
369
550
|
updateScrollShadow() {
|
|
370
551
|
const el = this.scrollBody()?.nativeElement;
|
|
371
552
|
if (!el)
|
|
@@ -383,15 +564,15 @@ class Dialog {
|
|
|
383
564
|
requestSubmit() {
|
|
384
565
|
this.elementRef.nativeElement.querySelector('form')?.requestSubmit();
|
|
385
566
|
}
|
|
386
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
387
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
567
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: Dialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
568
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: Dialog, isStandalone: true, selector: "mf-dialog", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fillBody: { classPropertyName: "fillBody", publicName: "fillBody", isSignal: true, isRequired: false, transformFunction: null }, autoClose: { classPropertyName: "autoClose", publicName: "autoClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close" }, host: { listeners: { "keydown.control.enter": "requestSubmit()", "keydown.meta.enter": "requestSubmit()" }, properties: { "class": "hostClasses()", "style.width.px": "customWidth()", "style.height.px": "customHeight()", "style.--mf-dir": "stateVariant() === 'drawer' ? 1 : null" } }, providers: [
|
|
388
569
|
{
|
|
389
570
|
provide: DialogSurface,
|
|
390
571
|
useFactory: () => inject(DialogSurface, { optional: true, skipSelf: true }) ?? new DialogSurface(),
|
|
391
572
|
},
|
|
392
|
-
], viewQueries: [{ propertyName: "scrollBody", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }], exportAs: ["mfDialog"], hostDirectives: [{ directive: i1.CdkDrag }], ngImport: i0, template: "<div\r\n class=\"flex shrink-0 items-start justify-between gap-3 px-6 pt-5 pb-4\"\r\n [class.border-b]=\"headerBorder()\"\r\n [class.border-border]=\"headerBorder()\"\r\n>\r\n <ng-content select=\"[dialog-header]\">\r\n @if (icon()) {\r\n <span\r\n class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-surface-alt text-fg-muted\"\r\n >\r\n <span mfIcon [size]=\"20\">{{ icon() }}</span>\r\n </span>\r\n }\r\n <div\r\n cdkDragHandle\r\n class=\"min-w-0 flex-1 pt-0.5\"\r\n [class.cursor-grab]=\"dragEnabled()\"\r\n [class.active:cursor-grabbing]=\"dragEnabled()\"\r\n >\r\n @if (title()) {\r\n <h2 class=\"truncate font-display text-title text-fg\">{{ title() }}</h2>\r\n }\r\n @if (subtitle()) {\r\n <p class=\"mt-0.5 truncate text-sm text-fg-muted\">{{ subtitle() }}</p>\r\n }\r\n </div>\r\n </ng-content>\r\n\r\n <div class=\"flex shrink-0 items-center gap-1\">\r\n @if (maximizeVisible()) {\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"surface.maximized() ? labels().fullscreenExit : labels().fullscreenEnter\"\r\n (click)=\"surface.toggleMaximize()\"\r\n >\r\n <span mfIcon [size]=\"18\">{{ surface.maximized() ? 'fullscreen_exit' : 'fullscreen' }}</span>\r\n </button>\r\n }\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"labels().close\"\r\n (click)=\"
|
|
573
|
+
], viewQueries: [{ propertyName: "scrollBody", first: true, predicate: ["scrollBody"], descendants: true, isSignal: true }], exportAs: ["mfDialog"], hostDirectives: [{ directive: i1.CdkDrag }], ngImport: i0, template: "<div\r\n class=\"flex shrink-0 items-start justify-between gap-3 px-6 pt-5 pb-4\"\r\n [class.border-b]=\"headerBorder()\"\r\n [class.border-border]=\"headerBorder()\"\r\n>\r\n <ng-content select=\"[dialog-header]\">\r\n @if (icon()) {\r\n <span\r\n class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-surface-alt text-fg-muted\"\r\n >\r\n <span mfIcon [size]=\"20\">{{ icon() }}</span>\r\n </span>\r\n }\r\n <div\r\n cdkDragHandle\r\n class=\"min-w-0 flex-1 pt-0.5\"\r\n [class.cursor-grab]=\"dragEnabled()\"\r\n [class.active:cursor-grabbing]=\"dragEnabled()\"\r\n >\r\n @if (title()) {\r\n <h2 [id]=\"titleId\" class=\"truncate font-display text-title text-fg\">{{ title() }}</h2>\r\n }\r\n @if (subtitle()) {\r\n <p class=\"mt-0.5 truncate text-sm text-fg-muted\">{{ subtitle() }}</p>\r\n }\r\n </div>\r\n </ng-content>\r\n\r\n <div class=\"flex shrink-0 items-center gap-1\">\r\n @if (maximizeVisible()) {\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"surface.maximized() ? labels().fullscreenExit : labels().fullscreenEnter\"\r\n (click)=\"surface.toggleMaximize()\"\r\n >\r\n <span mfIcon [size]=\"18\">{{ surface.maximized() ? 'fullscreen_exit' : 'fullscreen' }}</span>\r\n </button>\r\n }\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"labels().close\"\r\n (click)=\"onDismiss()\"\r\n >\r\n <span mfIcon [size]=\"20\">close</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div\r\n #scrollBody\r\n class=\"flex-1 min-h-0 px-6\"\r\n [class.py-4]=\"framed()\"\r\n [class.overflow-y-auto]=\"!fillBody()\"\r\n [class.flex]=\"fillBody()\"\r\n [class.flex-col]=\"fillBody()\"\r\n [class.overflow-hidden]=\"fillBody()\"\r\n (scroll)=\"updateScrollShadow()\"\r\n>\r\n <ng-content />\r\n</div>\r\n\r\n<div\r\n class=\"shrink-0 px-6 py-4 [&:not(:has(*))]:hidden\"\r\n [class.border-t]=\"footerBorder()\"\r\n [class.border-border]=\"footerBorder()\"\r\n>\r\n <ng-content select=\"[dialog-footer]\" />\r\n</div>\r\n\r\n@if (resizeHandleVisible()) {\r\n <button\r\n mfDialogResizeHandle\r\n type=\"button\"\r\n [ariaLabel]=\"labels().resize\"\r\n class=\"absolute right-1 bottom-1 flex h-4 w-4 cursor-se-resize items-center justify-center rounded-xs text-fg-subtle hover:text-fg-muted focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\"\r\n >\r\n <span mfIcon [size]=\"14\">south_east</span>\r\n </button>\r\n}\r\n", dependencies: [{ kind: "component", type: Button, selector: "button[mfButton], a[mfButton]", inputs: ["tone", "appearance", "size", "shape", "type", "loading", "iconStart", "iconEnd"], exportAs: ["mfButton"] }, { kind: "directive", type: Icon, selector: "span[mfIcon]", inputs: ["size", "filled"] }, { kind: "directive", type: DialogResizeHandle, selector: "[mfDialogResizeHandle]", inputs: ["ariaLabel"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }] });
|
|
393
574
|
}
|
|
394
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
575
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: Dialog, decorators: [{
|
|
395
576
|
type: Component,
|
|
396
577
|
args: [{ selector: 'mf-dialog', exportAs: 'mfDialog', imports: [Button, Icon, DialogResizeHandle, CdkDragHandle], hostDirectives: [CdkDrag], providers: [
|
|
397
578
|
{
|
|
@@ -402,10 +583,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
402
583
|
'[class]': 'hostClasses()',
|
|
403
584
|
'[style.width.px]': 'customWidth()',
|
|
404
585
|
'[style.height.px]': 'customHeight()',
|
|
586
|
+
// Çekmece kenarları FİZİKSEL çözülür (`DialogService` RTL'i zaten hesaba kattı) —
|
|
587
|
+
// motion.css'in `--mf-dir` çevirmesi burada çift çevirme yapmasın.
|
|
588
|
+
'[style.--mf-dir]': "stateVariant() === 'drawer' ? 1 : null",
|
|
405
589
|
'(keydown.control.enter)': 'requestSubmit()',
|
|
406
590
|
'(keydown.meta.enter)': 'requestSubmit()',
|
|
407
|
-
}, template: "<div\r\n class=\"flex shrink-0 items-start justify-between gap-3 px-6 pt-5 pb-4\"\r\n [class.border-b]=\"headerBorder()\"\r\n [class.border-border]=\"headerBorder()\"\r\n>\r\n <ng-content select=\"[dialog-header]\">\r\n @if (icon()) {\r\n <span\r\n class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-surface-alt text-fg-muted\"\r\n >\r\n <span mfIcon [size]=\"20\">{{ icon() }}</span>\r\n </span>\r\n }\r\n <div\r\n cdkDragHandle\r\n class=\"min-w-0 flex-1 pt-0.5\"\r\n [class.cursor-grab]=\"dragEnabled()\"\r\n [class.active:cursor-grabbing]=\"dragEnabled()\"\r\n >\r\n @if (title()) {\r\n <h2 class=\"truncate font-display text-title text-fg\">{{ title() }}</h2>\r\n }\r\n @if (subtitle()) {\r\n <p class=\"mt-0.5 truncate text-sm text-fg-muted\">{{ subtitle() }}</p>\r\n }\r\n </div>\r\n </ng-content>\r\n\r\n <div class=\"flex shrink-0 items-center gap-1\">\r\n @if (maximizeVisible()) {\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"surface.maximized() ? labels().fullscreenExit : labels().fullscreenEnter\"\r\n (click)=\"surface.toggleMaximize()\"\r\n >\r\n <span mfIcon [size]=\"18\">{{ surface.maximized() ? 'fullscreen_exit' : 'fullscreen' }}</span>\r\n </button>\r\n }\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"labels().close\"\r\n (click)=\"
|
|
408
|
-
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fillBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillBody", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], scrollBody: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }] } });
|
|
591
|
+
}, template: "<div\r\n class=\"flex shrink-0 items-start justify-between gap-3 px-6 pt-5 pb-4\"\r\n [class.border-b]=\"headerBorder()\"\r\n [class.border-border]=\"headerBorder()\"\r\n>\r\n <ng-content select=\"[dialog-header]\">\r\n @if (icon()) {\r\n <span\r\n class=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-surface-alt text-fg-muted\"\r\n >\r\n <span mfIcon [size]=\"20\">{{ icon() }}</span>\r\n </span>\r\n }\r\n <div\r\n cdkDragHandle\r\n class=\"min-w-0 flex-1 pt-0.5\"\r\n [class.cursor-grab]=\"dragEnabled()\"\r\n [class.active:cursor-grabbing]=\"dragEnabled()\"\r\n >\r\n @if (title()) {\r\n <h2 [id]=\"titleId\" class=\"truncate font-display text-title text-fg\">{{ title() }}</h2>\r\n }\r\n @if (subtitle()) {\r\n <p class=\"mt-0.5 truncate text-sm text-fg-muted\">{{ subtitle() }}</p>\r\n }\r\n </div>\r\n </ng-content>\r\n\r\n <div class=\"flex shrink-0 items-center gap-1\">\r\n @if (maximizeVisible()) {\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"surface.maximized() ? labels().fullscreenExit : labels().fullscreenEnter\"\r\n (click)=\"surface.toggleMaximize()\"\r\n >\r\n <span mfIcon [size]=\"18\">{{ surface.maximized() ? 'fullscreen_exit' : 'fullscreen' }}</span>\r\n </button>\r\n }\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"labels().close\"\r\n (click)=\"onDismiss()\"\r\n >\r\n <span mfIcon [size]=\"20\">close</span>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div\r\n #scrollBody\r\n class=\"flex-1 min-h-0 px-6\"\r\n [class.py-4]=\"framed()\"\r\n [class.overflow-y-auto]=\"!fillBody()\"\r\n [class.flex]=\"fillBody()\"\r\n [class.flex-col]=\"fillBody()\"\r\n [class.overflow-hidden]=\"fillBody()\"\r\n (scroll)=\"updateScrollShadow()\"\r\n>\r\n <ng-content />\r\n</div>\r\n\r\n<div\r\n class=\"shrink-0 px-6 py-4 [&:not(:has(*))]:hidden\"\r\n [class.border-t]=\"footerBorder()\"\r\n [class.border-border]=\"footerBorder()\"\r\n>\r\n <ng-content select=\"[dialog-footer]\" />\r\n</div>\r\n\r\n@if (resizeHandleVisible()) {\r\n <button\r\n mfDialogResizeHandle\r\n type=\"button\"\r\n [ariaLabel]=\"labels().resize\"\r\n class=\"absolute right-1 bottom-1 flex h-4 w-4 cursor-se-resize items-center justify-center rounded-xs text-fg-subtle hover:text-fg-muted focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\"\r\n >\r\n <span mfIcon [size]=\"14\">south_east</span>\r\n </button>\r\n}\r\n" }]
|
|
592
|
+
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fillBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillBody", required: false }] }], autoClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoClose", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], scrollBody: [{ type: i0.ViewChild, args: ['scrollBody', { isSignal: true }] }] } });
|
|
409
593
|
|
|
410
594
|
const TONE_ICON = {
|
|
411
595
|
danger: 'warning',
|
|
@@ -431,8 +615,8 @@ const TONE_BADGE_CLASS = {
|
|
|
431
615
|
* kendi çiziyor.
|
|
432
616
|
*/
|
|
433
617
|
class ConfirmDialog {
|
|
434
|
-
data =
|
|
435
|
-
dialogRef =
|
|
618
|
+
data = injectDialogData();
|
|
619
|
+
dialogRef = injectDialogRef();
|
|
436
620
|
labels = inject(MF_DIALOG_LABELS);
|
|
437
621
|
tone = computed(() => this.data.tone ?? 'neutral', /* @ts-ignore */
|
|
438
622
|
...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
@@ -477,17 +661,28 @@ class ConfirmDialog {
|
|
|
477
661
|
this.dialogRef.disableClose = false;
|
|
478
662
|
}
|
|
479
663
|
}
|
|
480
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
481
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.
|
|
664
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
665
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: ConfirmDialog, isStandalone: true, selector: "mf-confirm-dialog", host: { classAttribute: "contents" }, ngImport: i0, template: "<mf-dialog size=\"sm\" (close)=\"onCancel()\">\r\n <div dialog-header class=\"flex items-start gap-3\">\r\n <span\r\n class=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-md\"\r\n [class]=\"toneBadgeClass()\"\r\n >\r\n <span mfIcon [size]=\"22\">{{ toneIcon() }}</span>\r\n </span>\r\n <div class=\"min-w-0 flex-1 pt-1.5\">\r\n <h2 class=\"truncate font-display text-title text-fg\">{{ data.title }}</h2>\r\n </div>\r\n </div>\r\n\r\n <p class=\"text-sm text-fg-muted\">{{ data.content }}</p>\r\n\r\n @if (actionError()) {\r\n <p class=\"mt-3 text-sm text-danger\">{{ actionError() }}</p>\r\n }\r\n\r\n <div dialog-footer class=\"flex justify-end gap-2\">\r\n @if (!data.alert) {\r\n <button\r\n mfButton\r\n appearance=\"outlined\"\r\n tone=\"neutral\"\r\n type=\"button\"\r\n [disabled]=\"submitting()\"\r\n (click)=\"onCancel()\"\r\n >\r\n {{ data.cancelLabel ?? labels().confirmCancel }}\r\n </button>\r\n }\r\n <button\r\n mfButton\r\n [tone]=\"confirmTone()\"\r\n appearance=\"filled\"\r\n type=\"button\"\r\n [disabled]=\"submitting()\"\r\n [loading]=\"submitting()\"\r\n (click)=\"onConfirm()\"\r\n >\r\n {{ data.confirmLabel ?? (data.alert ? labels().confirmOk : labels().confirmConfirm) }}\r\n </button>\r\n </div>\r\n</mf-dialog>\r\n", dependencies: [{ kind: "component", type: Dialog, selector: "mf-dialog", inputs: ["title", "subtitle", "icon", "size", "fillBody", "autoClose"], outputs: ["close"], exportAs: ["mfDialog"] }, { kind: "component", type: Button, selector: "button[mfButton], a[mfButton]", inputs: ["tone", "appearance", "size", "shape", "type", "loading", "iconStart", "iconEnd"], exportAs: ["mfButton"] }, { kind: "directive", type: Icon, selector: "span[mfIcon]", inputs: ["size", "filled"] }] });
|
|
482
666
|
}
|
|
483
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
667
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: ConfirmDialog, decorators: [{
|
|
484
668
|
type: Component,
|
|
485
|
-
args: [{ selector: 'mf-confirm-dialog', imports: [Dialog, Button, Icon], host: { class: 'contents' }, template: "<mf-dialog size=\"sm\" (close)=\"onCancel()\">\r\n <div dialog-header class=\"flex items-start gap-3\">\r\n <span\r\n class=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-md\"\r\n [class]=\"toneBadgeClass()\"\r\n >\r\n <span mfIcon [size]=\"22\">{{ toneIcon() }}</span>\r\n </span>\r\n <div class=\"min-w-0 flex-1 pt-1.5\">\r\n <h2 class=\"truncate font-display text-title text-fg\">{{ data.title }}</h2>\r\n </div>\r\n </div>\r\n\r\n <p class=\"text-sm text-fg-muted\">{{ data.content }}</p>\r\n\r\n @if (actionError()) {\r\n <p class=\"mt-3 text-sm text-danger\">{{ actionError() }}</p>\r\n }\r\n\r\n <div dialog-footer class=\"flex justify-end gap-2\">\r\n @if (!data.alert) {\r\n <button\r\n mfButton\r\n appearance=\"outlined\"\r\n tone=\"neutral\"\r\n type=\"button\"\r\n [disabled]=\"submitting()\"\r\n (click)=\"onCancel()\"\r\n >\r\n {{ data.cancelLabel ?? labels().confirmCancel }}\r\n </button>\r\n }\r\n <button\r\n mfButton\r\n [tone]=\"confirmTone()\"\r\n appearance=\"filled\"\r\n type=\"button\"\r\n [disabled]=\"submitting()\"\r\n
|
|
669
|
+
args: [{ selector: 'mf-confirm-dialog', imports: [Dialog, Button, Icon], host: { class: 'contents' }, template: "<mf-dialog size=\"sm\" (close)=\"onCancel()\">\r\n <div dialog-header class=\"flex items-start gap-3\">\r\n <span\r\n class=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-md\"\r\n [class]=\"toneBadgeClass()\"\r\n >\r\n <span mfIcon [size]=\"22\">{{ toneIcon() }}</span>\r\n </span>\r\n <div class=\"min-w-0 flex-1 pt-1.5\">\r\n <h2 class=\"truncate font-display text-title text-fg\">{{ data.title }}</h2>\r\n </div>\r\n </div>\r\n\r\n <p class=\"text-sm text-fg-muted\">{{ data.content }}</p>\r\n\r\n @if (actionError()) {\r\n <p class=\"mt-3 text-sm text-danger\">{{ actionError() }}</p>\r\n }\r\n\r\n <div dialog-footer class=\"flex justify-end gap-2\">\r\n @if (!data.alert) {\r\n <button\r\n mfButton\r\n appearance=\"outlined\"\r\n tone=\"neutral\"\r\n type=\"button\"\r\n [disabled]=\"submitting()\"\r\n (click)=\"onCancel()\"\r\n >\r\n {{ data.cancelLabel ?? labels().confirmCancel }}\r\n </button>\r\n }\r\n <button\r\n mfButton\r\n [tone]=\"confirmTone()\"\r\n appearance=\"filled\"\r\n type=\"button\"\r\n [disabled]=\"submitting()\"\r\n [loading]=\"submitting()\"\r\n (click)=\"onConfirm()\"\r\n >\r\n {{ data.confirmLabel ?? (data.alert ? labels().confirmOk : labels().confirmConfirm) }}\r\n </button>\r\n </div>\r\n</mf-dialog>\r\n" }]
|
|
486
670
|
}] });
|
|
487
671
|
|
|
488
|
-
/** `--duration-fast` (styles.css) ile birebir — `animate-dialog-out`/`animate-sheet-out` keyframe'lerinin süresi. */
|
|
489
|
-
const EXIT_MS = 120;
|
|
490
672
|
const SHEET_QUERY = '(max-width: 639.98px)';
|
|
673
|
+
/** Mantıksal yerleşimi fiziksel kenara çevirir (`start`/`end` RTL'de yer değiştirir). */
|
|
674
|
+
function sideOf(placement, rtl) {
|
|
675
|
+
switch (placement) {
|
|
676
|
+
case 'center':
|
|
677
|
+
return null;
|
|
678
|
+
case 'start':
|
|
679
|
+
return rtl ? 'right' : 'left';
|
|
680
|
+
case 'end':
|
|
681
|
+
return rtl ? 'left' : 'right';
|
|
682
|
+
default:
|
|
683
|
+
return placement;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
491
686
|
function normalizeClass(value) {
|
|
492
687
|
if (!value)
|
|
493
688
|
return [];
|
|
@@ -499,9 +694,10 @@ function normalizeClass(value) {
|
|
|
499
694
|
* engelleme davranışının TAMAMI CDK'dan geliyor, burada TEKRAR YAZILMADI — bkz.
|
|
500
695
|
* projects/ui-kit/README.md "a11y checklist" bölümündeki "elle yazmak son çare" ilkesi).
|
|
501
696
|
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
697
|
+
* `open()` kite ait `MfDialogRef` döndürür (CDK `DialogRef` yüzeyini delege eder +
|
|
698
|
+
* `afterClosed()`/`state`/`surface`). İçerik component'i `injectDialogRef()`/
|
|
699
|
+
* `injectDialogData()` (bkz. dialog-ref.ts) kullanır — CDK'nın kendi `DialogRef`/
|
|
700
|
+
* `DIALOG_DATA` token'larını inject etmek de çalışmaya devam eder. Boyut/placement/maximize/drag/resize/sheet durumu
|
|
505
701
|
* `DialogSurface` (bkz. o dosya) üzerinden, `providers` ile o dialog'un injector'ına
|
|
506
702
|
* verilir — `Dialog` (dialog.ts) bunu DI'dan okuyarak render eder.
|
|
507
703
|
*
|
|
@@ -514,11 +710,13 @@ function normalizeClass(value) {
|
|
|
514
710
|
* Kapanış animasyonu: CDK'nın `DialogRef.close()`'u `overlayRef.dispose()`'u SENKRON
|
|
515
711
|
* çağırıyor, bir "kapanıyor" olayı/kancası yok. `closePredicate` bunun için bilinçli
|
|
516
712
|
* bir kaçamak — `false` döndürmek kapanmayı iptal ediyor: ilk çağrıda `surface.closing`'i
|
|
517
|
-
* `true` yapıp gerçek kapanmayı `
|
|
713
|
+
* `true` yapıp gerçek kapanmayı `exitDurationMs()` kadar geciktiriyoruz (panel bu sürede `Dialog`'un
|
|
518
714
|
* kendi reaktif `animate-dialog-out`/`animate-sheet-out`/`animate-drawer-out` class'ıyla
|
|
519
715
|
* görsel olarak kapanır), ikinci çağrıda (zaten `closing()===true`) gerçek `dispose()`'a
|
|
520
716
|
* izin veriyoruz. ESC/backdrop/programatik `dialogRef.close(...)` HEPSİ bu predicate'ten
|
|
521
|
-
* geçtiği için davranış tekdüze.
|
|
717
|
+
* geçtiği için davranış tekdüze. Animasyon sürerken gelen EK `close()` çağrıları
|
|
718
|
+
* yok sayılır (`disposeArmed` yalnızca zamanlayıcı tarafından kurulur) — X düğmesi +
|
|
719
|
+
* tüketicinin `(close)` handler'ı aynı anda kapatsa bile animasyon kesilmez. `prefers-reduced-motion` gecikmeyi tamamen atlıyor —
|
|
522
720
|
* AMA kirli-form kontrolünden SONRA: koruma reduced-motion kullanıcılarında da çalışmalı.
|
|
523
721
|
*
|
|
524
722
|
* **Kirli form koruması**: `surface.isDirty()` `true` dönerse kapanış iptal edilip
|
|
@@ -532,6 +730,7 @@ class DialogService {
|
|
|
532
730
|
injector = inject(Injector);
|
|
533
731
|
breakpointObserver = inject(BreakpointObserver);
|
|
534
732
|
labels = inject(MF_DIALOG_LABELS);
|
|
733
|
+
dir = inject(Directionality, { optional: true });
|
|
535
734
|
/** `ref` başına `DialogSurface` — tüketicinin kendi URL senkronizasyon mantığı, kirli-form durumunu PROAKTİF sormak için kullanabilir (kendi `closePredicate`'inin async akışıyla yarışmamak için). */
|
|
536
735
|
// `DialogRef<D, C>`'nin `config.providers` callback'i kendi generic'lerine yapısal
|
|
537
736
|
// olarak döngüsel referans veriyor (bkz. @angular/cdk/dialog) — `unknown` kullanmak
|
|
@@ -540,20 +739,43 @@ class DialogService {
|
|
|
540
739
|
// ilgisiz; `any` burada BİLEREK.
|
|
541
740
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
542
741
|
surfaces = new WeakMap();
|
|
742
|
+
/**
|
|
743
|
+
* Bir component'i ya da bir `TemplateRef'i açar (şablon yolu `<mf-drawer>` gibi
|
|
744
|
+
* bildirimsel sarmalayıcılar içindir — şablonun injector'ı da `DialogSurface'i görür).
|
|
745
|
+
*/
|
|
543
746
|
open(component, options) {
|
|
544
747
|
const surface = new DialogSurface();
|
|
545
748
|
const placement = options?.placement ?? 'center';
|
|
546
749
|
surface.size.set(options?.size ?? 'md');
|
|
547
750
|
surface.placement.set(placement);
|
|
751
|
+
const side = sideOf(placement, this.dir?.value === 'rtl');
|
|
752
|
+
surface.side.set(side);
|
|
753
|
+
const sheetOnMobile = (options?.sheetOnMobile ?? true) && side !== 'top' && side !== 'bottom';
|
|
548
754
|
surface.maximizable.set(options?.maximizable ?? false);
|
|
549
755
|
surface.draggable.set(options?.draggable ?? false);
|
|
550
756
|
surface.resizable.set(options?.resizable ?? false);
|
|
551
757
|
const position = createGlobalPositionStrategy(this.injector);
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
758
|
+
const place = () => {
|
|
759
|
+
if (side === 'right')
|
|
760
|
+
position.right('0').top('0');
|
|
761
|
+
else if (side === 'left')
|
|
762
|
+
position.left('0').top('0');
|
|
763
|
+
else if (side === 'top')
|
|
764
|
+
position.top('0').left('0');
|
|
765
|
+
else if (side === 'bottom')
|
|
766
|
+
position.bottom('0').left('0');
|
|
767
|
+
else
|
|
768
|
+
position.centerHorizontally().centerVertically();
|
|
769
|
+
};
|
|
770
|
+
place();
|
|
771
|
+
// Çıkış süresi CSS token'ından (`--mf-duration-exit`); reduced-motion'da 0.
|
|
772
|
+
const exitMs = exitDurationMs();
|
|
773
|
+
// Gerçek dispose'a SADECE çıkış zamanlayıcısı izin verir — bkz. sınıf yorumu.
|
|
774
|
+
let disposeArmed = false;
|
|
775
|
+
// Kirli-form onayı açıkken ikinci bir onay yığılmasın.
|
|
776
|
+
let discardPending = false;
|
|
777
|
+
let mfRef;
|
|
778
|
+
// CDK iki aşırı yükü (component / şablon) çalışma zamanında ayırt eder.
|
|
557
779
|
const ref = this.cdkDialog.open(component, {
|
|
558
780
|
data: options?.data,
|
|
559
781
|
panelClass: normalizeClass(options?.panelClass),
|
|
@@ -571,16 +793,32 @@ class DialogService {
|
|
|
571
793
|
// onayı açılmasına yol açabilir — gerçek bir kullanıcı senaryosunda
|
|
572
794
|
// tekrarlanan, doğrulanmış bir çakışma.
|
|
573
795
|
closeOnNavigation: false,
|
|
796
|
+
// `aria-modal` — arka plan zaten `aria-hidden`, ama ekran okuyucuların sanal imleci
|
|
797
|
+
// için modal olduğunu açıkça söylemek WAI-ARIA dialog deseninin gereği.
|
|
798
|
+
ariaModal: true,
|
|
799
|
+
// Verilmezse CDK konteyneri `<mf-dialog>`'un görünür başlığına `aria-labelledby` ile
|
|
800
|
+
// bağlanır (bkz. dialog.ts — `_addAriaLabelledBy`).
|
|
574
801
|
ariaLabel: options?.ariaLabel,
|
|
575
|
-
providers:
|
|
802
|
+
providers: (cdkRef) => {
|
|
803
|
+
mfRef = new MfDialogRef(cdkRef, surface);
|
|
804
|
+
return [
|
|
805
|
+
{ provide: DialogSurface, useValue: surface },
|
|
806
|
+
{ provide: MfDialogRef, useValue: mfRef },
|
|
807
|
+
];
|
|
808
|
+
},
|
|
576
809
|
closePredicate: (result) => {
|
|
577
|
-
// Çıkış animasyonu
|
|
578
|
-
if (
|
|
810
|
+
// Çıkış animasyonu bitti — zamanlayıcının kendi çağrısı, gerçek dispose'a izin ver.
|
|
811
|
+
if (disposeArmed)
|
|
579
812
|
return true;
|
|
580
|
-
//
|
|
813
|
+
// Animasyon ya da kirli-form onayı sürerken gelen ek çağrılar yok sayılır.
|
|
814
|
+
if (surface.closing() || discardPending)
|
|
815
|
+
return false;
|
|
816
|
+
// Kirli form koruması reduced-motion kısa devresinden ÖNCE kontrol edilir — aksi halde
|
|
581
817
|
// "animasyonu azalt" açık kullanıcılarda bu koruma hiç çalışmazdı.
|
|
582
818
|
if (surface.isDirty()) {
|
|
819
|
+
discardPending = true;
|
|
583
820
|
void this.confirmDiscard().then((discard) => {
|
|
821
|
+
discardPending = false;
|
|
584
822
|
if (!discard)
|
|
585
823
|
return;
|
|
586
824
|
surface.markClean();
|
|
@@ -588,30 +826,30 @@ class DialogService {
|
|
|
588
826
|
});
|
|
589
827
|
return false;
|
|
590
828
|
}
|
|
591
|
-
if (
|
|
829
|
+
if (exitMs === 0)
|
|
592
830
|
return true;
|
|
593
831
|
surface.closing.set(true);
|
|
594
832
|
ref.overlayRef.backdropElement?.classList.add('is-closing');
|
|
595
|
-
setTimeout(() =>
|
|
833
|
+
setTimeout(() => {
|
|
834
|
+
disposeArmed = true;
|
|
835
|
+
ref.close(result);
|
|
836
|
+
}, exitMs);
|
|
596
837
|
return false;
|
|
597
838
|
},
|
|
598
839
|
});
|
|
599
840
|
this.surfaces.set(ref, surface);
|
|
600
841
|
const breakpointSub = this.breakpointObserver.observe(SHEET_QUERY).subscribe(({ matches }) => {
|
|
601
|
-
|
|
602
|
-
|
|
842
|
+
const sheet = matches && sheetOnMobile;
|
|
843
|
+
surface.sheet.set(sheet);
|
|
844
|
+
if (sheet)
|
|
603
845
|
position.centerHorizontally().bottom('0');
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
position.right('0').top('0');
|
|
607
|
-
}
|
|
608
|
-
else {
|
|
609
|
-
position.centerHorizontally().centerVertically();
|
|
610
|
-
}
|
|
846
|
+
else
|
|
847
|
+
place();
|
|
611
848
|
position.apply();
|
|
612
849
|
});
|
|
613
850
|
ref.closed.subscribe(() => breakpointSub.unsubscribe());
|
|
614
|
-
|
|
851
|
+
// `providers` fabrikası CDK `open()` içinde SENKRON çağrılır — burada her zaman dolu.
|
|
852
|
+
return mfRef ?? new MfDialogRef(ref, surface);
|
|
615
853
|
}
|
|
616
854
|
/**
|
|
617
855
|
* Kayıt oluştur/düzenle formlarının TEK açılış noktası — sağdan drawer.
|
|
@@ -623,7 +861,11 @@ class DialogService {
|
|
|
623
861
|
* panel gibi) `md` içine sığmazsa `xl` (960px) geçilebilir.
|
|
624
862
|
*/
|
|
625
863
|
openDrawer(component, options) {
|
|
626
|
-
return this.open(component, {
|
|
864
|
+
return this.open(component, {
|
|
865
|
+
...options,
|
|
866
|
+
placement: options?.placement ?? 'right',
|
|
867
|
+
maximizable: false,
|
|
868
|
+
});
|
|
627
869
|
}
|
|
628
870
|
/** `Promise<boolean>` döner — `if (await dialog.confirm(...))` çağıran taraf için `.subscribe()` zincirinden daha sade. */
|
|
629
871
|
confirm(data) {
|
|
@@ -635,7 +877,7 @@ class DialogService {
|
|
|
635
877
|
// `ConfirmDialogData`'da ayrı bir `ariaLabel` alanı sağlayamıyor zaten.
|
|
636
878
|
ariaLabel: data.title,
|
|
637
879
|
});
|
|
638
|
-
return
|
|
880
|
+
return ref.afterClosed().then((result) => !!result);
|
|
639
881
|
}
|
|
640
882
|
/**
|
|
641
883
|
* Kirli-form kapanış korumasının kendi onay diyaloğu — `confirmDiscard`'ın açtığı
|
|
@@ -658,10 +900,14 @@ class DialogService {
|
|
|
658
900
|
cancelLabel: t.cancel,
|
|
659
901
|
});
|
|
660
902
|
}
|
|
661
|
-
/**
|
|
903
|
+
/**
|
|
904
|
+
* Tüketici bir ref'i kapatmadan ÖNCE kirli mi diye sormak istiyorsa — kendi `closePredicate`'inin
|
|
905
|
+
* async akışıyla yarışmamak için `DialogSurface`'e doğrudan erişim. `MfDialogRef` için
|
|
906
|
+
* `ref.surface` tercih edilir; ham CDK ref'i (ör. içerikte inject edilen) de kabul edilir.
|
|
907
|
+
*/
|
|
662
908
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
663
909
|
getSurface(ref) {
|
|
664
|
-
return this.surfaces.get(ref);
|
|
910
|
+
return ref instanceof MfDialogRef ? ref.surface : this.surfaces.get(ref);
|
|
665
911
|
}
|
|
666
912
|
/** `confirm()`'in silme kısayolu — `tone:'danger'` + varsayılan "Sil" etiketi. */
|
|
667
913
|
confirmDelete(data) {
|
|
@@ -675,12 +921,12 @@ class DialogService {
|
|
|
675
921
|
size: 'sm',
|
|
676
922
|
ariaLabel: data.title,
|
|
677
923
|
});
|
|
678
|
-
return
|
|
924
|
+
return ref.afterClosed().then(() => undefined);
|
|
679
925
|
}
|
|
680
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.
|
|
681
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.
|
|
926
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
927
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DialogService, providedIn: 'root' });
|
|
682
928
|
}
|
|
683
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.
|
|
929
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DialogService, decorators: [{
|
|
684
930
|
type: Injectable,
|
|
685
931
|
args: [{ providedIn: 'root' }]
|
|
686
932
|
}] });
|
|
@@ -696,5 +942,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
696
942
|
* Generated bundle index. Do not edit.
|
|
697
943
|
*/
|
|
698
944
|
|
|
699
|
-
export { ConfirmDialog, Dialog, DialogResizeHandle, DialogService, DialogSurface, dialogVariants };
|
|
945
|
+
export { ConfirmDialog, Dialog, DialogResizeHandle, DialogService, DialogSurface, MF_DIALOG_DATA, MfDialogRef, dialogVariants, injectDialogData, injectDialogRef };
|
|
700
946
|
//# sourceMappingURL=mesgflow-ui-kit-dialog.mjs.map
|