@rozie-ui/dialog-angular 0.0.0-stage → 0.2.4
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/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +91 -2
- package/dist/Dialog.d.ts +97 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/LICENSE +21 -0
- package/dist/README.md +92 -0
- package/dist/fesm2022/rozie-ui-dialog-angular.mjs +434 -0
- package/dist/fesm2022/rozie-ui-dialog-angular.mjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/internal/scrollLock.d.ts +4 -0
- package/dist/internal/scrollLock.d.ts.map +1 -0
- package/dist/rozie-ui-dialog-angular.d.ts.map +1 -0
- package/package.json +82 -3
- package/src/Dialog.ts +414 -0
- package/src/index.ts +1 -0
- package/src/internal/scrollLock.ts +48 -0
- package/src/themes/base.css +58 -0
- package/src/themes/bootstrap.css +37 -0
- package/src/themes/material.css +37 -0
- package/src/themes/shadcn.css +38 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, untracked, computed, signal, viewChild, contentChildren, inject, DestroyRef, effect, Renderer2, ElementRef, afterRenderEffect, TemplateRef, forwardRef, ContentChild, Component } from '@angular/core';
|
|
3
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
4
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
|
+
import { rozieModel, RozieSlot, createRozieAttrApplier, createRozieHostAttrsReader, rozieDisplay, rozieAttr } from '@rozie/runtime-angular';
|
|
6
|
+
|
|
7
|
+
// scrollLock.ts — a REF-COUNTED `<html>` scroll lock, shared by every `Dialog`
|
|
8
|
+
// instance compiled from this leaf's module (module-scope state — a plain
|
|
9
|
+
// per-instance toggle would unlock scrolling the moment ANY dialog closes,
|
|
10
|
+
// even while an OUTER dialog is still open — nested/stacked dialogs).
|
|
11
|
+
//
|
|
12
|
+
// The lock only actually applies on the 0 -> 1 transition and only actually
|
|
13
|
+
// releases on the 1 -> 0 transition. The ORIGINAL inline `overflow` value
|
|
14
|
+
// (captured on that first lock, not a hardcoded `''`) is restored when the
|
|
15
|
+
// count drops back to zero, so a page that already set its own inline
|
|
16
|
+
// `overflow` isn't clobbered by the second (or third...) dialog to close.
|
|
17
|
+
//
|
|
18
|
+
// Vendored (byte-identical) into every `@rozie-ui/dialog-*` leaf's
|
|
19
|
+
// `src/internal/` by `scripts/codegen.mjs`, unit-tested once here — the same
|
|
20
|
+
// "branchy, non-reactive helper -> src/internal" convention as the resizable
|
|
21
|
+
// family's `resizeMath.ts`.
|
|
22
|
+
let lockCount = 0;
|
|
23
|
+
let previousOverflow = null;
|
|
24
|
+
function applyScrollLock(lock) {
|
|
25
|
+
if (typeof document === 'undefined')
|
|
26
|
+
return;
|
|
27
|
+
const root = document.documentElement;
|
|
28
|
+
if (!root)
|
|
29
|
+
return;
|
|
30
|
+
if (lock) {
|
|
31
|
+
if (lockCount === 0) {
|
|
32
|
+
previousOverflow = root.style.overflow;
|
|
33
|
+
root.style.overflow = 'hidden';
|
|
34
|
+
}
|
|
35
|
+
lockCount += 1;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Guard against an unbalanced release (a lock() that was never applied,
|
|
39
|
+
// e.g. because `disableScrollLock` was toggled mid-flight) — never let the
|
|
40
|
+
// count go negative, which would require two extra locks to re-lock.
|
|
41
|
+
if (lockCount === 0)
|
|
42
|
+
return;
|
|
43
|
+
lockCount -= 1;
|
|
44
|
+
if (lockCount === 0) {
|
|
45
|
+
root.style.overflow = previousOverflow ?? '';
|
|
46
|
+
previousOverflow = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Test-only: reset the module-level counter between test cases. */
|
|
50
|
+
function _resetScrollLockForTests() {
|
|
51
|
+
lockCount = 0;
|
|
52
|
+
previousOverflow = null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
class Dialog {
|
|
56
|
+
/**
|
|
57
|
+
* Whether the dialog is shown (two-way `r-model`). The sole `model: true` prop — two-way bind it (`r-model:open` / `v-model:open` / `bind:open` / `[(open)]`) and Dialog reconciles the native `<dialog>` to it via `showModal()` / `close()`. Every close path (backdrop, Escape, programmatic `hide()`) writes `open = false` and emits `close`.
|
|
58
|
+
* @example
|
|
59
|
+
* <rozie-dialog [(open)]="confirmOpen" ariaLabelledby="confirm-title" />
|
|
60
|
+
*/
|
|
61
|
+
__rozieModelIn_open = input(undefined, { alias: 'open' });
|
|
62
|
+
openChange = output();
|
|
63
|
+
open = rozieModel(this.__rozieModelIn_open, this.openChange, false, { signal, computed, untracked });
|
|
64
|
+
/**
|
|
65
|
+
* Opt **out** of backdrop-click-to-dismiss. By default a click on the scrim (the `<dialog>` element itself, outside the content panel) closes the dialog with `reason: 'backdrop'`; set this to require an explicit action.
|
|
66
|
+
*/
|
|
67
|
+
disableBackdropClose = input(false);
|
|
68
|
+
/**
|
|
69
|
+
* Opt **out** of Escape-to-dismiss. By default the native `cancel` event (Esc) closes with `reason: 'escape'`; the component `preventDefault()`s it so the close always flows through the `open` model. Set this to keep the dialog open on Escape (e.g. a required confirmation).
|
|
70
|
+
*/
|
|
71
|
+
disableEscapeClose = input(false);
|
|
72
|
+
/**
|
|
73
|
+
* Opt **out** of locking `<html>` scroll while the dialog is open. By default `document.documentElement` `overflow` is set to `hidden` for the duration the dialog is shown; set this to leave background scrolling enabled.
|
|
74
|
+
*/
|
|
75
|
+
disableScrollLock = input(false);
|
|
76
|
+
/**
|
|
77
|
+
* What to focus when the dialog opens: a CSS selector matched inside the dialog content, or an Element. By default the native `showModal()` choice applies: the first element with `autofocus`, otherwise the first focusable element. Use it to start on a specific field (e.g. `initialFocus="input[name=title]"`) without waiting for the dialog to mount. A selector that matches nothing, or an element that is not focusable, leaves the native choice in place.
|
|
78
|
+
* @example
|
|
79
|
+
* <rozie-dialog [(open)]="renameOpen" initialFocus="#label-name" />
|
|
80
|
+
*/
|
|
81
|
+
initialFocus = input(null);
|
|
82
|
+
/**
|
|
83
|
+
* Accessible name for the dialog (`aria-label`) when there is no visible title to point at. Prefer `ariaLabelledby` when a visible heading exists.
|
|
84
|
+
*/
|
|
85
|
+
ariaLabel = input(null);
|
|
86
|
+
/**
|
|
87
|
+
* The `id` of the element that titles the dialog (`aria-labelledby`) — preferred over `ariaLabel` when a visible heading exists inside the dialog. On the Lit element the dialog lives in a shadow root while the heading is slotted light DOM, so the attribute alone cannot reach it; Dialog hands the browser the element directly (`ariaLabelledByElements`) where that is supported (Chrome/Edge 135+, Safari 16.4+) — elsewhere, use `ariaLabel` on Lit.
|
|
88
|
+
*/
|
|
89
|
+
ariaLabelledby = input(null);
|
|
90
|
+
panelEl = viewChild('panelEl');
|
|
91
|
+
close = output();
|
|
92
|
+
defaultTpl;
|
|
93
|
+
templates = input(undefined);
|
|
94
|
+
__rozieFills = contentChildren(RozieSlot, { descendants: true });
|
|
95
|
+
__rozieFillMap = computed(() => {
|
|
96
|
+
const map = Object.create(null);
|
|
97
|
+
for (const f of this.__rozieFills()) {
|
|
98
|
+
const k = f.rozieSlot();
|
|
99
|
+
if (k == null)
|
|
100
|
+
continue;
|
|
101
|
+
if (k === '__proto__' || k === 'constructor' || k === 'prototype')
|
|
102
|
+
continue;
|
|
103
|
+
map[k === '' ? 'defaultSlot' : k] = f.templateRef;
|
|
104
|
+
}
|
|
105
|
+
return map;
|
|
106
|
+
});
|
|
107
|
+
__rozieWatchInitial_0 = true;
|
|
108
|
+
constructor() {
|
|
109
|
+
inject(DestroyRef).onDestroy(() => {
|
|
110
|
+
this.setScrollLock(false);
|
|
111
|
+
this.pressStartedInside = false;
|
|
112
|
+
const el = this.dialogEl;
|
|
113
|
+
const back = this.returnFocusTo;
|
|
114
|
+
this.dialogEl = null;
|
|
115
|
+
this.returnFocusTo = null;
|
|
116
|
+
if (!el || !el.open)
|
|
117
|
+
return;
|
|
118
|
+
if (el.isConnected)
|
|
119
|
+
el.close();
|
|
120
|
+
if (!back)
|
|
121
|
+
return;
|
|
122
|
+
setTimeout(() => {
|
|
123
|
+
// Lost: on <body>, or stranded on a shadow host whose root holds no focus
|
|
124
|
+
// and which is not focusable itself (the dialog's removed subtree was
|
|
125
|
+
// inside it).
|
|
126
|
+
const active = this.deepActiveElement();
|
|
127
|
+
const lost = !active || active === document.body || !!active.shadowRoot && active.tabIndex < 0;
|
|
128
|
+
if (back.isConnected && lost)
|
|
129
|
+
back.focus();
|
|
130
|
+
}, 0);
|
|
131
|
+
});
|
|
132
|
+
effect(() => {
|
|
133
|
+
const __watchVal = (() => this.open())();
|
|
134
|
+
untracked(() => {
|
|
135
|
+
if (this.__rozieWatchInitial_0) {
|
|
136
|
+
this.__rozieWatchInitial_0 = false;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
((isOpen) => {
|
|
140
|
+
this.sync(isOpen);
|
|
141
|
+
})(__watchVal);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
ngAfterViewInit() {
|
|
146
|
+
this.sync(this.open());
|
|
147
|
+
}
|
|
148
|
+
dialogEl = null;
|
|
149
|
+
// Whether THIS instance currently holds one count of the shared scroll lock.
|
|
150
|
+
holdsLock = false;
|
|
151
|
+
// The element focused when the dialog opened, for the unmount-while-open
|
|
152
|
+
// focus return (a normal close gets the native return from close()).
|
|
153
|
+
returnFocusTo = null;
|
|
154
|
+
// Whether the press that is about to produce a `click` began INSIDE the panel.
|
|
155
|
+
// A press that starts on content (selecting text, a drag) and is released over
|
|
156
|
+
// the scrim yields a `click` whose target is the common ancestor, the <dialog>
|
|
157
|
+
// itself; without this it would be mistaken for a backdrop click.
|
|
158
|
+
pressStartedInside = false;
|
|
159
|
+
// Lock/unlock <html> scroll for this instance. The actual lock/unlock is
|
|
160
|
+
// REF-COUNTED (./internal/scrollLock) across every Dialog instance sharing this
|
|
161
|
+
// leaf's module, because a naive per-instance toggle unlocks scrolling the
|
|
162
|
+
// moment ANY dialog closes, even while an OUTER dialog is still open. This
|
|
163
|
+
// wrapper releases only a count this instance took: a dialog that mounts closed
|
|
164
|
+
// (or closes twice) must not release a count another open dialog holds. The
|
|
165
|
+
// opt-out is read when locking only, so toggling it while open still releases.
|
|
166
|
+
setScrollLock = (lock) => {
|
|
167
|
+
if (lock === this.holdsLock)
|
|
168
|
+
return;
|
|
169
|
+
if (lock && this.disableScrollLock())
|
|
170
|
+
return;
|
|
171
|
+
this.holdsLock = lock;
|
|
172
|
+
applyScrollLock(lock);
|
|
173
|
+
};
|
|
174
|
+
// The element that really has focus. `document.activeElement` stops at the
|
|
175
|
+
// outermost shadow host (on Lit the trigger lives inside a component's shadow
|
|
176
|
+
// root, so it reports that component), so walk each shadowRoot.activeElement.
|
|
177
|
+
deepActiveElement = () => {
|
|
178
|
+
let active = typeof document === 'undefined' ? null : document.activeElement;
|
|
179
|
+
while (active && active.shadowRoot && active.shadowRoot.activeElement)
|
|
180
|
+
active = active.shadowRoot.activeElement;
|
|
181
|
+
return active;
|
|
182
|
+
};
|
|
183
|
+
// Focus `initialFocus` after showModal() has made its native choice. A selector
|
|
184
|
+
// is matched inside the panel and, on Lit, inside the light-DOM content
|
|
185
|
+
// assigned to the panel's <slot> (which panel.querySelector cannot see).
|
|
186
|
+
focusInitial = (panel) => {
|
|
187
|
+
const target = this.initialFocus();
|
|
188
|
+
if (!target)
|
|
189
|
+
return;
|
|
190
|
+
let node = null;
|
|
191
|
+
if (typeof target === 'string') {
|
|
192
|
+
node = panel.querySelector(target);
|
|
193
|
+
const slot = node ? null : panel.querySelector('slot');
|
|
194
|
+
const assigned = slot && typeof slot.assignedElements === 'function' ? slot.assignedElements({
|
|
195
|
+
flatten: true
|
|
196
|
+
}) : [];
|
|
197
|
+
for (let i = 0; !node && i < assigned.length; i++) {
|
|
198
|
+
node = assigned[i].matches(target) ? assigned[i] : assigned[i].querySelector(target);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
node = target;
|
|
203
|
+
}
|
|
204
|
+
if (node && typeof node.focus === 'function')
|
|
205
|
+
node.focus();
|
|
206
|
+
};
|
|
207
|
+
// `aria-labelledby` is an IDREF, and an IDREF never crosses a shadow-root
|
|
208
|
+
// boundary. Where the <dialog> lives inside an element's shadow root (the Lit
|
|
209
|
+
// target) the heading it names is slotted LIGHT DOM, so the attribute resolves to
|
|
210
|
+
// nothing and the dialog has no accessible name. Element reflection can point
|
|
211
|
+
// across the boundary (to an element in an ancestor tree), so when the id is not
|
|
212
|
+
// reachable from the dialog's own root, hand the browser the element directly.
|
|
213
|
+
// A no-op outside a shadow root, and where the browser lacks the property.
|
|
214
|
+
bridgeLabelledBy = (el) => {
|
|
215
|
+
const id = this.ariaLabelledby();
|
|
216
|
+
const root = el.getRootNode();
|
|
217
|
+
if (!id || !root || !root.host || typeof root.getElementById !== 'function')
|
|
218
|
+
return;
|
|
219
|
+
if (root.getElementById(id) || !('ariaLabelledByElements' in el))
|
|
220
|
+
return;
|
|
221
|
+
const outer = root.host.getRootNode();
|
|
222
|
+
const heading = outer && typeof outer.getElementById === 'function' ? outer.getElementById(id) : null;
|
|
223
|
+
if (heading)
|
|
224
|
+
el.ariaLabelledByElements = [heading];
|
|
225
|
+
};
|
|
226
|
+
// Reconcile the native <dialog> to the desired open state. Guarded on the
|
|
227
|
+
// native `el.open` flag (showModal throws if already open; close is a no-op when
|
|
228
|
+
// closed). Reads $refs in a post-mount callback (ROZ123-safe).
|
|
229
|
+
//
|
|
230
|
+
// The ref lives on the inner panel <div> (which the emitter types as
|
|
231
|
+
// HTMLDivElement), and we reach the <dialog> via `panel.parentElement` cast to
|
|
232
|
+
// HTMLDialogElement. This sidesteps an emitter gap: the per-target ref-type map
|
|
233
|
+
// has no `dialog` case, so a ref placed directly on <dialog> would be typed the
|
|
234
|
+
// generic HTMLElement (no `.open`/`.showModal()`/`.close()`), failing strict
|
|
235
|
+
// leaf typecheck. Fixing it here keeps the change source-only (no emitter edit).
|
|
236
|
+
sync = (isOpen) => {
|
|
237
|
+
const panel = this.panelEl()?.nativeElement;
|
|
238
|
+
const el = (panel && panel.parentElement);
|
|
239
|
+
if (!el)
|
|
240
|
+
return;
|
|
241
|
+
this.dialogEl = el;
|
|
242
|
+
if (isOpen) {
|
|
243
|
+
if (!el.open) {
|
|
244
|
+
const active = this.deepActiveElement();
|
|
245
|
+
this.returnFocusTo = active instanceof HTMLElement ? active : null;
|
|
246
|
+
this.bridgeLabelledBy(el);
|
|
247
|
+
el.showModal();
|
|
248
|
+
this.focusInitial(panel);
|
|
249
|
+
}
|
|
250
|
+
this.setScrollLock(true);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
if (el.open)
|
|
254
|
+
el.close();
|
|
255
|
+
this.returnFocusTo = null;
|
|
256
|
+
this.setScrollLock(false);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
// ---- close funnel (single $emit site) ----------------------------------
|
|
260
|
+
closeWith = (reason) => {
|
|
261
|
+
this.open.set(false), this.__rozieCvaOnChange(false);
|
|
262
|
+
this.close.emit({
|
|
263
|
+
reason
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
// ---- handlers ----------------------------------------------------------
|
|
267
|
+
// Native Esc fires `cancel` on the <dialog>. preventDefault so WE drive the
|
|
268
|
+
// close through the model (keeping `open` in sync); honor the opt-out.
|
|
269
|
+
onCancel = (e) => {
|
|
270
|
+
if (e)
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
if (this.disableEscapeClose())
|
|
273
|
+
return;
|
|
274
|
+
this.closeWith('escape');
|
|
275
|
+
};
|
|
276
|
+
// Remember whether a press began on the panel's content (anywhere but the
|
|
277
|
+
// <dialog> box itself), so the `click` that follows can tell a real scrim click
|
|
278
|
+
// from the end of a drag that merely finished over the scrim.
|
|
279
|
+
onPointerDown = (e) => {
|
|
280
|
+
const panel = this.panelEl()?.nativeElement;
|
|
281
|
+
const el = panel && panel.parentElement;
|
|
282
|
+
this.pressStartedInside = !!(e && el && e.target !== el);
|
|
283
|
+
};
|
|
284
|
+
// A click whose target IS the <dialog> element (not its panel/children) is a
|
|
285
|
+
// backdrop click — the ::backdrop is part of the dialog box. We compare the
|
|
286
|
+
// real `e.target` (reliable even under Solid's event delegation) to the dialog
|
|
287
|
+
// element resolved via the panel ref's parent. A click whose press started
|
|
288
|
+
// inside the panel is not one (see `pressStartedInside`).
|
|
289
|
+
onClick = (e) => {
|
|
290
|
+
const startedInside = this.pressStartedInside;
|
|
291
|
+
this.pressStartedInside = false;
|
|
292
|
+
if (this.disableBackdropClose() || startedInside)
|
|
293
|
+
return;
|
|
294
|
+
const panel = this.panelEl()?.nativeElement;
|
|
295
|
+
const el = panel && panel.parentElement;
|
|
296
|
+
if (e && el && e.target === el)
|
|
297
|
+
this.closeWith('backdrop');
|
|
298
|
+
};
|
|
299
|
+
// The native `close` event: fired by `el.close()` from our own reconcile (by then
|
|
300
|
+
// the model is already false, and the dialog may even have been re-opened), but
|
|
301
|
+
// also by closes WE did not drive — a `<form method="dialog">` submit, a stray
|
|
302
|
+
// `dialog.close()`. For those the model is still true over a closed dialog and
|
|
303
|
+
// would stay stuck (writing `open = true` again changes nothing), so fold them
|
|
304
|
+
// into the close funnel. Not during teardown: $onUnmount closes the dialog
|
|
305
|
+
// itself after clearing `dialogEl`.
|
|
306
|
+
onNativeClose = () => {
|
|
307
|
+
const el = this.dialogEl;
|
|
308
|
+
if (!el || el.open || !this.open())
|
|
309
|
+
return;
|
|
310
|
+
this.closeWith('programmatic');
|
|
311
|
+
};
|
|
312
|
+
// ---- lifecycle ---------------------------------------------------------
|
|
313
|
+
// ---- imperative handle -------------------------------------------------
|
|
314
|
+
// show()/hide() — named to avoid the `open` model + `@close` event collisions.
|
|
315
|
+
// hide() on a dialog that is not open is a no-op: there is nothing to dismiss, so
|
|
316
|
+
// it must not emit a `close` for a dismissal that never happened.
|
|
317
|
+
show = () => {
|
|
318
|
+
this.open.set(true), this.__rozieCvaOnChange(true);
|
|
319
|
+
};
|
|
320
|
+
hide = () => {
|
|
321
|
+
if (!this.open())
|
|
322
|
+
return;
|
|
323
|
+
this.closeWith('programmatic');
|
|
324
|
+
};
|
|
325
|
+
__rozieCvaOnChange = () => { };
|
|
326
|
+
__rozieCvaOnTouchedFn = () => { };
|
|
327
|
+
__rozieCvaDisabled = signal(false);
|
|
328
|
+
writeValue(v) {
|
|
329
|
+
this.open.set(v ?? false);
|
|
330
|
+
}
|
|
331
|
+
registerOnChange(fn) {
|
|
332
|
+
this.__rozieCvaOnChange = fn;
|
|
333
|
+
}
|
|
334
|
+
registerOnTouched(fn) {
|
|
335
|
+
this.__rozieCvaOnTouchedFn = fn;
|
|
336
|
+
}
|
|
337
|
+
setDisabledState(isDisabled) {
|
|
338
|
+
this.__rozieCvaDisabled.set(isDisabled);
|
|
339
|
+
}
|
|
340
|
+
__rozieCvaOnTouched() {
|
|
341
|
+
this.__rozieCvaOnTouchedFn();
|
|
342
|
+
}
|
|
343
|
+
static ngTemplateContextGuard(_dir, _ctx) {
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
__rozieDestroyRef = inject(DestroyRef);
|
|
347
|
+
rozieSpread_0 = viewChild('rozieSpread_0');
|
|
348
|
+
__rozieApplyAttrs = createRozieAttrApplier(inject(Renderer2));
|
|
349
|
+
__rozieGetHostAttrs = createRozieHostAttrsReader(inject(ElementRef));
|
|
350
|
+
__rozieSpread_0_effect = afterRenderEffect(() => {
|
|
351
|
+
const el = this.rozieSpread_0()?.nativeElement;
|
|
352
|
+
if (!el)
|
|
353
|
+
return;
|
|
354
|
+
this.__rozieApplyAttrs(el, this.__rozieGetHostAttrs());
|
|
355
|
+
});
|
|
356
|
+
rozieListenersTarget_1 = viewChild('rozieListenersTarget_1');
|
|
357
|
+
__rozieListenersRenderer = inject(Renderer2);
|
|
358
|
+
__rozieListenersDisposers_1 = [];
|
|
359
|
+
__rozieListenersDestroyRegistered_1 = false;
|
|
360
|
+
__rozieListenersEffect_1 = effect(() => {
|
|
361
|
+
const el = this.rozieListenersTarget_1()?.nativeElement;
|
|
362
|
+
if (!el)
|
|
363
|
+
return;
|
|
364
|
+
for (const off of this.__rozieListenersDisposers_1)
|
|
365
|
+
off();
|
|
366
|
+
this.__rozieListenersDisposers_1 = [];
|
|
367
|
+
const obj = {};
|
|
368
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
369
|
+
if (k === '__proto__' || k === 'constructor' || k === 'prototype')
|
|
370
|
+
continue;
|
|
371
|
+
if (typeof v !== 'function')
|
|
372
|
+
continue;
|
|
373
|
+
const norm = k.startsWith('on') ? k.slice(2).toLowerCase() : k;
|
|
374
|
+
const dispose = this.__rozieListenersRenderer.listen(el, norm, v);
|
|
375
|
+
this.__rozieListenersDisposers_1.push(dispose);
|
|
376
|
+
}
|
|
377
|
+
if (!this.__rozieListenersDestroyRegistered_1) {
|
|
378
|
+
this.__rozieListenersDestroyRegistered_1 = true;
|
|
379
|
+
this.__rozieDestroyRef.onDestroy(() => {
|
|
380
|
+
for (const off of this.__rozieListenersDisposers_1)
|
|
381
|
+
off();
|
|
382
|
+
this.__rozieListenersDisposers_1 = [];
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
rozieDisplay(v) { return rozieDisplay(v); }
|
|
387
|
+
rozieAttr(v) { return rozieAttr(v); }
|
|
388
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.22", ngImport: i0, type: Dialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
389
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.22", type: Dialog, isStandalone: true, selector: "rozie-dialog", inputs: { __rozieModelIn_open: { classPropertyName: "__rozieModelIn_open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, disableBackdropClose: { classPropertyName: "disableBackdropClose", publicName: "disableBackdropClose", isSignal: true, isRequired: false, transformFunction: null }, disableEscapeClose: { classPropertyName: "disableEscapeClose", publicName: "disableEscapeClose", isSignal: true, isRequired: false, transformFunction: null }, disableScrollLock: { classPropertyName: "disableScrollLock", publicName: "disableScrollLock", isSignal: true, isRequired: false, transformFunction: null }, initialFocus: { classPropertyName: "initialFocus", publicName: "initialFocus", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, templates: { classPropertyName: "templates", publicName: "templates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openChange: "openChange", close: "close" }, host: { listeners: { "focusout": "__rozieCvaOnTouched()" } }, providers: [
|
|
390
|
+
{
|
|
391
|
+
provide: NG_VALUE_ACCESSOR,
|
|
392
|
+
useExisting: forwardRef(() => Dialog),
|
|
393
|
+
multi: true,
|
|
394
|
+
},
|
|
395
|
+
], queries: [{ propertyName: "__rozieFills", predicate: RozieSlot, descendants: true, isSignal: true }, { propertyName: "defaultTpl", first: true, predicate: ["defaultSlot"], descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "panelEl", first: true, predicate: ["panelEl"], descendants: true, isSignal: true }, { propertyName: "rozieSpread_0", first: true, predicate: ["rozieSpread_0"], descendants: true, isSignal: true }, { propertyName: "rozieListenersTarget_1", first: true, predicate: ["rozieListenersTarget_1"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
396
|
+
|
|
397
|
+
<dialog class="rozie-dialog" [attr.aria-label]="rozieAttr(ariaLabel())" [attr.aria-labelledby]="rozieAttr(ariaLabelledby())" #rozieSpread_0 (cancel)="onCancel($event)" (close)="onNativeClose()" (pointerdown)="onPointerDown($event)" (click)="onClick($event)" #rozieListenersTarget_1>
|
|
398
|
+
|
|
399
|
+
<div class="rozie-dialog-panel" #panelEl>
|
|
400
|
+
<ng-container *ngTemplateOutlet="(defaultTpl ?? __rozieFillMap()['defaultSlot'] ?? templates()?.['defaultSlot'])" />
|
|
401
|
+
</div>
|
|
402
|
+
</dialog>
|
|
403
|
+
|
|
404
|
+
`, isInline: true, styles: [":host(rozie-dialog){display:contents}@media(prefers-reduced-motion:no-preference){.rozie-dialog{transition:opacity var(--rozie-dialog-transition, var(--rdg-transition, .15s ease)),transform var(--rozie-dialog-transition, var(--rdg-transition, .15s ease)),overlay .15s ease allow-discrete,display .15s ease allow-discrete;opacity:1;transform:translateY(0) scale(1)}.rozie-dialog:not([open]){opacity:0;transform:translateY(.5rem) scale(.98)}@starting-style{.rozie-dialog[open]{opacity:0;transform:translateY(.5rem) scale(.98)}}.rozie-dialog::backdrop{transition:opacity var(--rozie-dialog-transition, var(--rdg-transition, .15s ease)),overlay .15s ease allow-discrete,display .15s ease allow-discrete;opacity:1}.rozie-dialog:not([open])::backdrop{opacity:0}@starting-style{.rozie-dialog[open]::backdrop{opacity:0}}}.rozie-dialog{margin:auto;padding:0;width:var(--rozie-dialog-width, var(--rdg-width, auto));max-width:var(--rozie-dialog-max-width, var(--rdg-max-width, min(32rem, calc(100vw - 2rem) )));max-height:var(--rozie-dialog-max-height, var(--rdg-max-height, calc(100vh - 2rem) ));border:var(--rozie-dialog-border, var(--rdg-border, none));border-radius:var(--rozie-dialog-radius, var(--rdg-radius, .75rem));background:var(--rozie-dialog-bg, var(--rdg-bg, #fff));color:var(--rozie-dialog-color, var(--rdg-color, inherit));box-shadow:var(--rozie-dialog-shadow, var(--rdg-shadow, 0 10px 38px rgba(0, 0, 0, .35), 0 0 1px rgba(0, 0, 0, .25)));overflow:auto}.rozie-dialog::backdrop{background:var(--rozie-dialog-backdrop-bg, var(--rdg-backdrop-bg, rgba(0, 0, 0, .5)));backdrop-filter:var(--rozie-dialog-backdrop-filter, var(--rdg-backdrop-filter, none))}.rozie-dialog-panel{padding:var(--rozie-dialog-padding, var(--rdg-padding, 1.5rem));font:var(--rozie-dialog-font, inherit)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
405
|
+
}
|
|
406
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.22", ngImport: i0, type: Dialog, decorators: [{
|
|
407
|
+
type: Component,
|
|
408
|
+
args: [{ selector: 'rozie-dialog', standalone: true, imports: [NgTemplateOutlet], template: `
|
|
409
|
+
|
|
410
|
+
<dialog class="rozie-dialog" [attr.aria-label]="rozieAttr(ariaLabel())" [attr.aria-labelledby]="rozieAttr(ariaLabelledby())" #rozieSpread_0 (cancel)="onCancel($event)" (close)="onNativeClose()" (pointerdown)="onPointerDown($event)" (click)="onClick($event)" #rozieListenersTarget_1>
|
|
411
|
+
|
|
412
|
+
<div class="rozie-dialog-panel" #panelEl>
|
|
413
|
+
<ng-container *ngTemplateOutlet="(defaultTpl ?? __rozieFillMap()['defaultSlot'] ?? templates()?.['defaultSlot'])" />
|
|
414
|
+
</div>
|
|
415
|
+
</dialog>
|
|
416
|
+
|
|
417
|
+
`, providers: [
|
|
418
|
+
{
|
|
419
|
+
provide: NG_VALUE_ACCESSOR,
|
|
420
|
+
useExisting: forwardRef(() => Dialog),
|
|
421
|
+
multi: true,
|
|
422
|
+
},
|
|
423
|
+
], host: { '(focusout)': '__rozieCvaOnTouched()' }, styles: [":host(rozie-dialog){display:contents}@media(prefers-reduced-motion:no-preference){.rozie-dialog{transition:opacity var(--rozie-dialog-transition, var(--rdg-transition, .15s ease)),transform var(--rozie-dialog-transition, var(--rdg-transition, .15s ease)),overlay .15s ease allow-discrete,display .15s ease allow-discrete;opacity:1;transform:translateY(0) scale(1)}.rozie-dialog:not([open]){opacity:0;transform:translateY(.5rem) scale(.98)}@starting-style{.rozie-dialog[open]{opacity:0;transform:translateY(.5rem) scale(.98)}}.rozie-dialog::backdrop{transition:opacity var(--rozie-dialog-transition, var(--rdg-transition, .15s ease)),overlay .15s ease allow-discrete,display .15s ease allow-discrete;opacity:1}.rozie-dialog:not([open])::backdrop{opacity:0}@starting-style{.rozie-dialog[open]::backdrop{opacity:0}}}.rozie-dialog{margin:auto;padding:0;width:var(--rozie-dialog-width, var(--rdg-width, auto));max-width:var(--rozie-dialog-max-width, var(--rdg-max-width, min(32rem, calc(100vw - 2rem) )));max-height:var(--rozie-dialog-max-height, var(--rdg-max-height, calc(100vh - 2rem) ));border:var(--rozie-dialog-border, var(--rdg-border, none));border-radius:var(--rozie-dialog-radius, var(--rdg-radius, .75rem));background:var(--rozie-dialog-bg, var(--rdg-bg, #fff));color:var(--rozie-dialog-color, var(--rdg-color, inherit));box-shadow:var(--rozie-dialog-shadow, var(--rdg-shadow, 0 10px 38px rgba(0, 0, 0, .35), 0 0 1px rgba(0, 0, 0, .25)));overflow:auto}.rozie-dialog::backdrop{background:var(--rozie-dialog-backdrop-bg, var(--rdg-backdrop-bg, rgba(0, 0, 0, .5)));backdrop-filter:var(--rozie-dialog-backdrop-filter, var(--rdg-backdrop-filter, none))}.rozie-dialog-panel{padding:var(--rozie-dialog-padding, var(--rdg-padding, 1.5rem));font:var(--rozie-dialog-font, inherit)}\n"] }]
|
|
424
|
+
}], ctorParameters: () => [], propDecorators: { defaultTpl: [{
|
|
425
|
+
type: ContentChild,
|
|
426
|
+
args: ['defaultSlot', { read: TemplateRef }]
|
|
427
|
+
}] } });
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Generated bundle index. Do not edit.
|
|
431
|
+
*/
|
|
432
|
+
|
|
433
|
+
export { Dialog };
|
|
434
|
+
//# sourceMappingURL=rozie-ui-dialog-angular.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rozie-ui-dialog-angular.mjs","sources":["../../src/internal/scrollLock.ts","../../src/Dialog.ts","../../src/rozie-ui-dialog-angular.ts"],"sourcesContent":["// scrollLock.ts — a REF-COUNTED `<html>` scroll lock, shared by every `Dialog`\n// instance compiled from this leaf's module (module-scope state — a plain\n// per-instance toggle would unlock scrolling the moment ANY dialog closes,\n// even while an OUTER dialog is still open — nested/stacked dialogs).\n//\n// The lock only actually applies on the 0 -> 1 transition and only actually\n// releases on the 1 -> 0 transition. The ORIGINAL inline `overflow` value\n// (captured on that first lock, not a hardcoded `''`) is restored when the\n// count drops back to zero, so a page that already set its own inline\n// `overflow` isn't clobbered by the second (or third...) dialog to close.\n//\n// Vendored (byte-identical) into every `@rozie-ui/dialog-*` leaf's\n// `src/internal/` by `scripts/codegen.mjs`, unit-tested once here — the same\n// \"branchy, non-reactive helper -> src/internal\" convention as the resizable\n// family's `resizeMath.ts`.\nlet lockCount = 0;\nlet previousOverflow: string | null = null;\n\nexport function applyScrollLock(lock: boolean): void {\n if (typeof document === 'undefined') return;\n const root = document.documentElement;\n if (!root) return;\n\n if (lock) {\n if (lockCount === 0) {\n previousOverflow = root.style.overflow;\n root.style.overflow = 'hidden';\n }\n lockCount += 1;\n return;\n }\n\n // Guard against an unbalanced release (a lock() that was never applied,\n // e.g. because `disableScrollLock` was toggled mid-flight) — never let the\n // count go negative, which would require two extra locks to re-lock.\n if (lockCount === 0) return;\n lockCount -= 1;\n if (lockCount === 0) {\n root.style.overflow = previousOverflow ?? '';\n previousOverflow = null;\n }\n}\n\n/** Test-only: reset the module-level counter between test cases. */\nexport function _resetScrollLockForTests(): void {\n lockCount = 0;\n previousOverflow = null;\n}\n","import { Component, ContentChild, DestroyRef, ElementRef, Renderer2, TemplateRef, ViewEncapsulation, afterRenderEffect, computed, contentChildren, effect, forwardRef, inject, input, output, signal, untracked, viewChild } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { RozieSlot, createRozieAttrApplier, createRozieHostAttrsReader, rozieAttr as __rozieAttr, rozieDisplay as __rozieDisplay, rozieModel } from '@rozie/runtime-angular';\n\nimport { applyScrollLock as applySharedScrollLock } from './internal/scrollLock';\n\n// ---- native reconcile ---------------------------------------------------\n// The <dialog> element, cached by sync() so $onUnmount can reach it without\n// reading $refs during teardown.\n\n/** Why the dialog closed: a scrim click, the Escape key, or a programmatic `hide()`. */\nexport type DialogCloseReason = 'backdrop' | 'escape' | 'programmatic';\n/** The `close` event payload. */\nexport interface DialogClosePayload {\n reason: DialogCloseReason;\n}\n\ninterface DefaultCtx {}\n\n@Component({\n selector: 'rozie-dialog',\n standalone: true,\n imports: [NgTemplateOutlet],\n template: `\n\n <dialog class=\"rozie-dialog\" [attr.aria-label]=\"rozieAttr(ariaLabel())\" [attr.aria-labelledby]=\"rozieAttr(ariaLabelledby())\" #rozieSpread_0 (cancel)=\"onCancel($event)\" (close)=\"onNativeClose()\" (pointerdown)=\"onPointerDown($event)\" (click)=\"onClick($event)\" #rozieListenersTarget_1>\n \n <div class=\"rozie-dialog-panel\" #panelEl>\n <ng-container *ngTemplateOutlet=\"(defaultTpl ?? __rozieFillMap()['defaultSlot'] ?? templates()?.['defaultSlot'])\" />\n </div>\n </dialog>\n\n `,\n styles: [`\n :host(rozie-dialog) { display: contents; }\n @media (prefers-reduced-motion: no-preference) {\n .rozie-dialog {\n transition: opacity var(--rozie-dialog-transition, var(--rdg-transition, 0.15s ease)), transform var(--rozie-dialog-transition, var(--rdg-transition, 0.15s ease)), overlay 0.15s ease allow-discrete, display 0.15s ease allow-discrete;\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n .rozie-dialog:not([open]) {\n opacity: 0;\n transform: translateY(0.5rem) scale(0.98);\n }\n @starting-style {\n .rozie-dialog[open] {\n opacity: 0;\n transform: translateY(0.5rem) scale(0.98);\n }\n }\n .rozie-dialog::backdrop {\n transition: opacity var(--rozie-dialog-transition, var(--rdg-transition, 0.15s ease)), overlay 0.15s ease allow-discrete, display 0.15s ease allow-discrete;\n opacity: 1;\n }\n .rozie-dialog:not([open])::backdrop {\n opacity: 0;\n }\n @starting-style {\n .rozie-dialog[open]::backdrop {\n opacity: 0;\n }\n }\n }\n .rozie-dialog {\n margin: auto; /* centers in the top layer */\n padding: 0;\n width: var(--rozie-dialog-width, var(--rdg-width, auto));\n max-width: var(--rozie-dialog-max-width, var(--rdg-max-width, min(32rem, calc(100vw - 2rem))));\n max-height: var(--rozie-dialog-max-height, var(--rdg-max-height, calc(100vh - 2rem)));\n border: var(--rozie-dialog-border, var(--rdg-border, none));\n border-radius: var(--rozie-dialog-radius, var(--rdg-radius, 0.75rem));\n background: var(--rozie-dialog-bg, var(--rdg-bg, #fff));\n color: var(--rozie-dialog-color, var(--rdg-color, inherit));\n box-shadow: var(--rozie-dialog-shadow, var(--rdg-shadow, 0 10px 38px rgba(0, 0, 0, 0.35), 0 0 1px rgba(0, 0, 0, 0.25)));\n overflow: auto;\n }\n .rozie-dialog::backdrop {\n background: var(--rozie-dialog-backdrop-bg, var(--rdg-backdrop-bg, rgba(0, 0, 0, 0.5)));\n backdrop-filter: var(--rozie-dialog-backdrop-filter, var(--rdg-backdrop-filter, none));\n }\n .rozie-dialog-panel {\n padding: var(--rozie-dialog-padding, var(--rdg-padding, 1.5rem));\n font: var(--rozie-dialog-font, inherit);\n }\n `],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Dialog),\n multi: true,\n },\n ],\n host: { '(focusout)': '__rozieCvaOnTouched()' },\n})\nexport class Dialog {\n /**\n * Whether the dialog is shown (two-way `r-model`). The sole `model: true` prop — two-way bind it (`r-model:open` / `v-model:open` / `bind:open` / `[(open)]`) and Dialog reconciles the native `<dialog>` to it via `showModal()` / `close()`. Every close path (backdrop, Escape, programmatic `hide()`) writes `open = false` and emits `close`.\n * @example\n * <rozie-dialog [(open)]=\"confirmOpen\" ariaLabelledby=\"confirm-title\" />\n */\n readonly __rozieModelIn_open = input<boolean | undefined>(undefined, { alias: 'open' });\n openChange = output<boolean>();\n open = rozieModel<boolean, import('@angular/core').ModelSignal<boolean>>(this.__rozieModelIn_open, this.openChange, false, { signal, computed, untracked });\n /**\n * Opt **out** of backdrop-click-to-dismiss. By default a click on the scrim (the `<dialog>` element itself, outside the content panel) closes the dialog with `reason: 'backdrop'`; set this to require an explicit action.\n */\n disableBackdropClose = input<boolean>(false);\n /**\n * Opt **out** of Escape-to-dismiss. By default the native `cancel` event (Esc) closes with `reason: 'escape'`; the component `preventDefault()`s it so the close always flows through the `open` model. Set this to keep the dialog open on Escape (e.g. a required confirmation).\n */\n disableEscapeClose = input<boolean>(false);\n /**\n * Opt **out** of locking `<html>` scroll while the dialog is open. By default `document.documentElement` `overflow` is set to `hidden` for the duration the dialog is shown; set this to leave background scrolling enabled.\n */\n disableScrollLock = input<boolean>(false);\n /**\n * What to focus when the dialog opens: a CSS selector matched inside the dialog content, or an Element. By default the native `showModal()` choice applies: the first element with `autofocus`, otherwise the first focusable element. Use it to start on a specific field (e.g. `initialFocus=\"input[name=title]\"`) without waiting for the dialog to mount. A selector that matches nothing, or an element that is not focusable, leaves the native choice in place.\n * @example\n * <rozie-dialog [(open)]=\"renameOpen\" initialFocus=\"#label-name\" />\n */\n initialFocus = input<(string | Element) | null>(null);\n /**\n * Accessible name for the dialog (`aria-label`) when there is no visible title to point at. Prefer `ariaLabelledby` when a visible heading exists.\n */\n ariaLabel = input<(string) | null>(null);\n /**\n * The `id` of the element that titles the dialog (`aria-labelledby`) — preferred over `ariaLabel` when a visible heading exists inside the dialog. On the Lit element the dialog lives in a shadow root while the heading is slotted light DOM, so the attribute alone cannot reach it; Dialog hands the browser the element directly (`ariaLabelledByElements`) where that is supported (Chrome/Edge 135+, Safari 16.4+) — elsewhere, use `ariaLabel` on Lit.\n */\n ariaLabelledby = input<(string) | null>(null);\n panelEl = viewChild<ElementRef<HTMLDivElement>>('panelEl');\n close = output<DialogClosePayload>();\n @ContentChild('defaultSlot', { read: TemplateRef }) defaultTpl?: TemplateRef<DefaultCtx>;\n templates = input<Record<string, TemplateRef<unknown>> | undefined>(undefined);\n __rozieFills = contentChildren(RozieSlot, { descendants: true });\n __rozieFillMap = computed(() => {\n const map = Object.create(null) as Record<string, TemplateRef<unknown>>;\n for (const f of this.__rozieFills()) {\n const k = f.rozieSlot();\n if (k == null) continue;\n if (k === '__proto__' || k === 'constructor' || k === 'prototype') continue;\n map[k === '' ? 'defaultSlot' : k] = f.templateRef;\n }\n return map;\n });\n private __rozieWatchInitial_0 = true;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.setScrollLock(false);\n this.pressStartedInside = false;\n const el = this.dialogEl;\n const back = this.returnFocusTo;\n this.dialogEl = null;\n this.returnFocusTo = null;\n if (!el || !el.open) return;\n if (el.isConnected) el.close();\n if (!back) return;\n setTimeout(() => {\n // Lost: on <body>, or stranded on a shadow host whose root holds no focus\n // and which is not focusable itself (the dialog's removed subtree was\n // inside it).\n const active = this.deepActiveElement();\n const lost = !active || active === document.body || !!active.shadowRoot && active.tabIndex < 0;\n if (back.isConnected && lost) back.focus();\n }, 0);\n });\n effect(() => { const __watchVal = (() => this.open())(); untracked(() => { if (this.__rozieWatchInitial_0) { this.__rozieWatchInitial_0 = false; return; } ((isOpen: any) => {\n this.sync(isOpen);\n })(__watchVal); }); });\n }\n\n ngAfterViewInit() {\n this.sync(this.open());\n }\n\n dialogEl: HTMLDialogElement | null = null;\n // Whether THIS instance currently holds one count of the shared scroll lock.\n holdsLock = false;\n // The element focused when the dialog opened, for the unmount-while-open\n // focus return (a normal close gets the native return from close()).\n returnFocusTo: HTMLElement | null = null;\n // Whether the press that is about to produce a `click` began INSIDE the panel.\n // A press that starts on content (selecting text, a drag) and is released over\n // the scrim yields a `click` whose target is the common ancestor, the <dialog>\n // itself; without this it would be mistaken for a backdrop click.\n pressStartedInside = false;\n // Lock/unlock <html> scroll for this instance. The actual lock/unlock is\n // REF-COUNTED (./internal/scrollLock) across every Dialog instance sharing this\n // leaf's module, because a naive per-instance toggle unlocks scrolling the\n // moment ANY dialog closes, even while an OUTER dialog is still open. This\n // wrapper releases only a count this instance took: a dialog that mounts closed\n // (or closes twice) must not release a count another open dialog holds. The\n // opt-out is read when locking only, so toggling it while open still releases.\n setScrollLock = (lock: any) => {\n if (lock === this.holdsLock) return;\n if (lock && this.disableScrollLock()) return;\n this.holdsLock = lock;\n applySharedScrollLock(lock);\n };\n // The element that really has focus. `document.activeElement` stops at the\n // outermost shadow host (on Lit the trigger lives inside a component's shadow\n // root, so it reports that component), so walk each shadowRoot.activeElement.\n deepActiveElement = () => {\n let active: any = typeof document === 'undefined' ? null : document.activeElement;\n while (active && active.shadowRoot && active.shadowRoot.activeElement) active = active.shadowRoot.activeElement;\n return active;\n };\n // Focus `initialFocus` after showModal() has made its native choice. A selector\n // is matched inside the panel and, on Lit, inside the light-DOM content\n // assigned to the panel's <slot> (which panel.querySelector cannot see).\n focusInitial = (panel: any) => {\n const target: any = this.initialFocus();\n if (!target) return;\n let node: any = null;\n if (typeof target === 'string') {\n node = panel.querySelector(target);\n const slot: any = node ? null : panel.querySelector('slot');\n const assigned: any[] = slot && typeof slot.assignedElements === 'function' ? slot.assignedElements({\n flatten: true\n }) : [];\n for (let i = 0; !node && i < assigned.length; i++) {\n node = assigned[i].matches(target) ? assigned[i] : assigned[i].querySelector(target);\n }\n } else {\n node = target;\n }\n if (node && typeof node.focus === 'function') node.focus();\n };\n // `aria-labelledby` is an IDREF, and an IDREF never crosses a shadow-root\n // boundary. Where the <dialog> lives inside an element's shadow root (the Lit\n // target) the heading it names is slotted LIGHT DOM, so the attribute resolves to\n // nothing and the dialog has no accessible name. Element reflection can point\n // across the boundary (to an element in an ancestor tree), so when the id is not\n // reachable from the dialog's own root, hand the browser the element directly.\n // A no-op outside a shadow root, and where the browser lacks the property.\n bridgeLabelledBy = (el: any) => {\n const id = this.ariaLabelledby();\n const root: any = el.getRootNode();\n if (!id || !root || !root.host || typeof root.getElementById !== 'function') return;\n if (root.getElementById(id) || !('ariaLabelledByElements' in el)) return;\n const outer: any = root.host.getRootNode();\n const heading = outer && typeof outer.getElementById === 'function' ? outer.getElementById(id) : null;\n if (heading) el.ariaLabelledByElements = [heading];\n };\n // Reconcile the native <dialog> to the desired open state. Guarded on the\n // native `el.open` flag (showModal throws if already open; close is a no-op when\n // closed). Reads $refs in a post-mount callback (ROZ123-safe).\n //\n // The ref lives on the inner panel <div> (which the emitter types as\n // HTMLDivElement), and we reach the <dialog> via `panel.parentElement` cast to\n // HTMLDialogElement. This sidesteps an emitter gap: the per-target ref-type map\n // has no `dialog` case, so a ref placed directly on <dialog> would be typed the\n // generic HTMLElement (no `.open`/`.showModal()`/`.close()`), failing strict\n // leaf typecheck. Fixing it here keeps the change source-only (no emitter edit).\n sync = (isOpen: any) => {\n const panel = this.panelEl()?.nativeElement;\n const el = (panel && panel.parentElement) as HTMLDialogElement | null;\n if (!el) return;\n this.dialogEl = el;\n if (isOpen) {\n if (!el.open) {\n const active = this.deepActiveElement();\n this.returnFocusTo = active instanceof HTMLElement ? active : null;\n this.bridgeLabelledBy(el);\n el.showModal();\n this.focusInitial(panel);\n }\n this.setScrollLock(true);\n } else {\n if (el.open) el.close();\n this.returnFocusTo = null;\n this.setScrollLock(false);\n }\n };\n // ---- close funnel (single $emit site) ----------------------------------\n closeWith = (reason: any) => {\n this.open.set(false), this.__rozieCvaOnChange(false);\n this.close.emit({\n reason\n });\n };\n // ---- handlers ----------------------------------------------------------\n // Native Esc fires `cancel` on the <dialog>. preventDefault so WE drive the\n // close through the model (keeping `open` in sync); honor the opt-out.\n onCancel = (e: any) => {\n if (e) e.preventDefault();\n if (this.disableEscapeClose()) return;\n this.closeWith('escape');\n };\n // Remember whether a press began on the panel's content (anywhere but the\n // <dialog> box itself), so the `click` that follows can tell a real scrim click\n // from the end of a drag that merely finished over the scrim.\n onPointerDown = (e: any) => {\n const panel = this.panelEl()?.nativeElement;\n const el = panel && panel.parentElement;\n this.pressStartedInside = !!(e && el && e.target !== el);\n };\n // A click whose target IS the <dialog> element (not its panel/children) is a\n // backdrop click — the ::backdrop is part of the dialog box. We compare the\n // real `e.target` (reliable even under Solid's event delegation) to the dialog\n // element resolved via the panel ref's parent. A click whose press started\n // inside the panel is not one (see `pressStartedInside`).\n onClick = (e: any) => {\n const startedInside = this.pressStartedInside;\n this.pressStartedInside = false;\n if (this.disableBackdropClose() || startedInside) return;\n const panel = this.panelEl()?.nativeElement;\n const el = panel && panel.parentElement;\n if (e && el && e.target === el) this.closeWith('backdrop');\n };\n // The native `close` event: fired by `el.close()` from our own reconcile (by then\n // the model is already false, and the dialog may even have been re-opened), but\n // also by closes WE did not drive — a `<form method=\"dialog\">` submit, a stray\n // `dialog.close()`. For those the model is still true over a closed dialog and\n // would stay stuck (writing `open = true` again changes nothing), so fold them\n // into the close funnel. Not during teardown: $onUnmount closes the dialog\n // itself after clearing `dialogEl`.\n onNativeClose = () => {\n const el = this.dialogEl;\n if (!el || el.open || !this.open()) return;\n this.closeWith('programmatic');\n };\n // ---- lifecycle ---------------------------------------------------------\n // ---- imperative handle -------------------------------------------------\n // show()/hide() — named to avoid the `open` model + `@close` event collisions.\n // hide() on a dialog that is not open is a no-op: there is nothing to dismiss, so\n // it must not emit a `close` for a dismissal that never happened.\n show: () => void = () => {\n this.open.set(true), this.__rozieCvaOnChange(true);\n };\n hide: () => void = () => {\n if (!this.open()) return;\n this.closeWith('programmatic');\n };\n\n private __rozieCvaOnChange: (v: boolean) => void = () => {};\n private __rozieCvaOnTouchedFn: () => void = () => {};\n protected __rozieCvaDisabled = signal(false);\n\n writeValue(v: boolean | null): void {\n this.open.set(v ?? false);\n }\n registerOnChange(fn: (v: boolean) => void): void {\n this.__rozieCvaOnChange = fn;\n }\n registerOnTouched(fn: () => void): void {\n this.__rozieCvaOnTouchedFn = fn;\n }\n setDisabledState(isDisabled: boolean): void {\n this.__rozieCvaDisabled.set(isDisabled);\n }\n __rozieCvaOnTouched(): void {\n this.__rozieCvaOnTouchedFn();\n }\n\n static ngTemplateContextGuard(\n _dir: Dialog,\n _ctx: unknown,\n ): _ctx is DefaultCtx {\n return true;\n }\n\n private __rozieDestroyRef = inject(DestroyRef);\n\n private rozieSpread_0 = viewChild<ElementRef>('rozieSpread_0');\n\n private __rozieApplyAttrs = createRozieAttrApplier(inject(Renderer2));\n\n private __rozieGetHostAttrs = createRozieHostAttrsReader(inject(ElementRef));\n\n private __rozieSpread_0_effect = afterRenderEffect(() => {\n const el = this.rozieSpread_0()?.nativeElement;\n if (!el) return;\n this.__rozieApplyAttrs(el, this.__rozieGetHostAttrs());\n });\n\n private rozieListenersTarget_1 = viewChild<ElementRef>('rozieListenersTarget_1');\n\n private __rozieListenersRenderer = inject(Renderer2);\n\n private __rozieListenersDisposers_1: Array<() => void> = [];\n\n private __rozieListenersDestroyRegistered_1 = false;\n\n private __rozieListenersEffect_1 = effect(() => {\n const el = this.rozieListenersTarget_1()?.nativeElement;\n if (!el) return;\n for (const off of this.__rozieListenersDisposers_1) off();\n this.__rozieListenersDisposers_1 = [];\n const obj: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (k === '__proto__' || k === 'constructor' || k === 'prototype') continue;\n if (typeof v !== 'function') continue;\n const norm = k.startsWith('on') ? k.slice(2).toLowerCase() : k;\n const dispose = this.__rozieListenersRenderer.listen(el, norm, v as EventListener);\n this.__rozieListenersDisposers_1.push(dispose);\n }\n if (!this.__rozieListenersDestroyRegistered_1) {\n this.__rozieListenersDestroyRegistered_1 = true;\n this.__rozieDestroyRef.onDestroy(() => {\n for (const off of this.__rozieListenersDisposers_1) off();\n this.__rozieListenersDisposers_1 = [];\n });\n }\n });\n\n rozieDisplay(v: unknown): string { return __rozieDisplay(v); }\n\n rozieAttr(v: unknown): string | null { return __rozieAttr(v); }\n}\n\nexport default Dialog;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["applySharedScrollLock","__rozieDisplay","__rozieAttr"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrollLock.d.ts","sourceRoot":"","sources":["../../src/internal/scrollLock.ts"],"names":[],"mappings":"AAkBA,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAuBnD;AAED,oEAAoE;AACpE,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rozie-ui-dialog-angular.d.ts","sourceRoot":"","sources":["../src/rozie-ui-dialog-angular.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,cAAc,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,85 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rozie-ui/dialog-angular",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.4",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": false,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"description": "Idiomatic Angular headless WAI-ARIA modal dialog on the native <dialog> element (top-layer, ::backdrop scrim, focus trap, Esc-to-dismiss, scroll-lock) — one accessible Rozie source compiled to Angular.",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"rozie",
|
|
10
|
+
"rozie-ui",
|
|
11
|
+
"dialog",
|
|
12
|
+
"modal",
|
|
13
|
+
"popup",
|
|
14
|
+
"overlay",
|
|
15
|
+
"headless",
|
|
16
|
+
"accessibility",
|
|
17
|
+
"aria",
|
|
18
|
+
"component",
|
|
19
|
+
"angular"
|
|
20
|
+
],
|
|
21
|
+
"author": "One Learning Community (https://github.com/One-Learning-Community)",
|
|
22
|
+
"homepage": "https://github.com/One-Learning-Community/rozie.js#readme",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/One-Learning-Community/rozie.js.git",
|
|
26
|
+
"directory": "packages/ui/dialog/packages/angular"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/One-Learning-Community/rozie.js/issues"
|
|
30
|
+
},
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"default": "./dist/fesm2022/rozie-ui-dialog-angular.mjs"
|
|
35
|
+
},
|
|
36
|
+
"./themes/*": "./src/themes/*",
|
|
37
|
+
"./source": {
|
|
38
|
+
"types": "./src/index.ts",
|
|
39
|
+
"default": "./src/index.ts"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"src",
|
|
45
|
+
"CHANGELOG.md"
|
|
46
|
+
],
|
|
47
|
+
"module": "./dist/fesm2022/rozie-ui-dialog-angular.mjs",
|
|
48
|
+
"types": "./dist/index.d.ts",
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@angular/core": "^19",
|
|
51
|
+
"@angular/common": "^19",
|
|
52
|
+
"@angular/forms": "^19"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"@angular/core": {
|
|
56
|
+
"optional": false
|
|
57
|
+
},
|
|
58
|
+
"@angular/common": {
|
|
59
|
+
"optional": false
|
|
60
|
+
},
|
|
61
|
+
"@angular/forms": {
|
|
62
|
+
"optional": false
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"access": "public"
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"tslib": "^2",
|
|
70
|
+
"@rozie/runtime-angular": "^0.10.1"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@angular/common": "^19",
|
|
74
|
+
"@angular/compiler": "^19",
|
|
75
|
+
"@angular/compiler-cli": "^19",
|
|
76
|
+
"@angular/core": "^19",
|
|
77
|
+
"@angular/forms": "^19",
|
|
78
|
+
"ng-packagr": "^19",
|
|
79
|
+
"typescript": "~5.6.0"
|
|
80
|
+
},
|
|
81
|
+
"scripts": {
|
|
82
|
+
"build": "ng-packagr -p ng-package.json -c tsconfig.lib.json",
|
|
83
|
+
"typecheck": "echo 'source+dist; ng-packagr declaration emit at build'"
|
|
84
|
+
}
|
|
6
85
|
}
|