@neural-ui/core 1.8.1 → 1.8.3
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.
|
@@ -24,6 +24,8 @@ class NeuDialogComponent {
|
|
|
24
24
|
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
25
25
|
/** Tamaño del panel: sm | md | lg | xl | full. / Panel size: sm | md | lg | xl | full. */
|
|
26
26
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
27
|
+
/** Ajusta la altura al contenido o al viewport disponible. / Fits height to content or to the available viewport. */
|
|
28
|
+
layout = input('auto', ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
27
29
|
/** Si es true, el backdrop y el botón cerrar no funcionan. / If true, the backdrop and close button do not work. */
|
|
28
30
|
disableClose = input(false, ...(ngDevMode ? [{ debugName: "disableClose" }] : /* istanbul ignore next */ []));
|
|
29
31
|
/** Adapta el panel a mobile/full-width cuando el viewport es estrecho. */
|
|
@@ -103,7 +105,7 @@ class NeuDialogComponent {
|
|
|
103
105
|
return Array.from(panel.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter((element) => !element.hasAttribute('aria-hidden'));
|
|
104
106
|
}
|
|
105
107
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
106
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuDialogComponent, isStandalone: true, selector: "neu-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disableClose: { classPropertyName: "disableClose", publicName: "disableClose", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "class.neu-dialog--open": "open()", "attr.aria-hidden": "!open()" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
108
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuDialogComponent, isStandalone: true, selector: "neu-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, disableClose: { classPropertyName: "disableClose", publicName: "disableClose", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "class.neu-dialog--open": "open()", "class.neu-dialog--responsive": "responsive()", "class.neu-dialog--layout-auto": "layout() === \"auto\"", "class.neu-dialog--layout-viewport": "layout() === \"viewport\"", "attr.aria-hidden": "!open()" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
107
109
|
@if (open()) {
|
|
108
110
|
<!-- Backdrop -->
|
|
109
111
|
<div
|
|
@@ -112,48 +114,55 @@ class NeuDialogComponent {
|
|
|
112
114
|
aria-hidden="true"
|
|
113
115
|
></div>
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
117
|
+
<div class="neu-dialog__viewport">
|
|
118
|
+
<!-- Panel -->
|
|
119
|
+
<div
|
|
120
|
+
#panel
|
|
121
|
+
class="neu-dialog__panel neu-dialog__panel--{{ size() }}"
|
|
122
|
+
[class.neu-dialog__panel--responsive]="responsive()"
|
|
123
|
+
[class.neu-dialog__panel--layout-auto]="layout() === 'auto'"
|
|
124
|
+
[class.neu-dialog__panel--layout-viewport]="layout() === 'viewport'"
|
|
125
|
+
role="dialog"
|
|
126
|
+
tabindex="-1"
|
|
127
|
+
[id]="'neu-dialog-' + _uid"
|
|
128
|
+
[attr.aria-labelledby]="'neu-dialog-title-' + _uid"
|
|
129
|
+
[attr.aria-modal]="true"
|
|
130
|
+
(keydown)="onPanelKeydown($event)"
|
|
131
|
+
>
|
|
132
|
+
<!-- Header -->
|
|
133
|
+
<div class="neu-dialog__header">
|
|
134
|
+
<h2 class="neu-dialog__title" [id]="'neu-dialog-title-' + _uid">{{ title() }}</h2>
|
|
135
|
+
@if (!disableClose()) {
|
|
136
|
+
<button
|
|
137
|
+
class="neu-dialog__close"
|
|
138
|
+
type="button"
|
|
139
|
+
aria-label="Close dialog"
|
|
140
|
+
(click)="close()"
|
|
141
|
+
>
|
|
142
|
+
<neu-icon name="lucideX" size="1.125rem" />
|
|
143
|
+
</button>
|
|
144
|
+
}
|
|
145
|
+
</div>
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
<!-- Body -->
|
|
148
|
+
<div class="neu-dialog__body">
|
|
149
|
+
<ng-content />
|
|
150
|
+
</div>
|
|
146
151
|
|
|
147
|
-
|
|
148
|
-
|
|
152
|
+
<!-- Footer (opcional via slot) -->
|
|
153
|
+
<ng-content select="[neu-dialog-footer]" />
|
|
154
|
+
</div>
|
|
149
155
|
</div>
|
|
150
156
|
}
|
|
151
|
-
`, isInline: true, styles: [".neu-dialog-backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}@keyframes neu-backdrop-in{0%{opacity:0}to{opacity:1}}.neu-dialog-panel{background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);outline:none;display:flex;flex-direction:column;max-height:
|
|
157
|
+
`, isInline: true, styles: [".neu-dialog-backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}@keyframes neu-backdrop-in{0%{opacity:0}to{opacity:1}}.neu-dialog-panel{background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);outline:none;display:flex;flex-direction:column;width:min(100vw - 2rem,var(--neu-dialog-width-md, 560px));height:var(--neu-dialog-height, auto);max-height:var(--neu-dialog-max-height, 90vh);margin:var(--neu-dialog-margin, auto);overflow:hidden;animation:neu-dialog-in .2s cubic-bezier(.22,1,.36,1) both}.neu-dialog-panel--sm{width:min(100vw - 2rem,var(--neu-dialog-width-sm, 400px))}.neu-dialog-panel--md{width:min(100vw - 2rem,var(--neu-dialog-width-md, 560px))}.neu-dialog-panel--lg{width:min(100vw - 2rem,var(--neu-dialog-width-lg, 720px))}.neu-dialog-panel--xl{width:min(100vw - 2rem,var(--neu-dialog-width-xl, 900px))}.neu-dialog-panel--full{width:min(100vw - 2rem,var(--neu-dialog-width-full, 1120px))}:where(.neu-dialog-panel--layout-viewport){--neu-dialog-height: 90vh;--neu-dialog-body-flex: 1 1 auto}@keyframes neu-dialog-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}neu-dialog{display:contents}:where(neu-dialog.neu-dialog--layout-viewport){--neu-dialog-height: 90vh;--neu-dialog-body-flex: 1 1 auto}@supports (height: 100dvh){:where(neu-dialog),:where(.neu-dialog-panel){--neu-dialog-max-height: 90dvh}:where(neu-dialog.neu-dialog--layout-viewport),:where(.neu-dialog-panel--layout-viewport){--neu-dialog-height: 90dvh}}.neu-dialog__backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}.neu-dialog__viewport{position:fixed;inset:var(--neu-dialog-inset, 0);z-index:var(--neu-z-modal, 200);display:flex;align-items:center;justify-content:center;pointer-events:none;min-width:0;min-height:0}.neu-dialog__panel{position:relative;margin:var(--neu-dialog-margin, auto);background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);display:flex;flex-direction:column;height:var(--neu-dialog-height, auto);max-height:var(--neu-dialog-max-height, 90vh);max-width:100%;overflow:hidden;pointer-events:auto;animation:neu-dialog-in .2s cubic-bezier(.22,1,.36,1) both}.neu-dialog__panel--sm{width:min(100%,var(--neu-dialog-width-sm, 400px))}.neu-dialog__panel--md{width:min(100%,var(--neu-dialog-width-md, 560px))}.neu-dialog__panel--lg{width:min(100%,var(--neu-dialog-width-lg, 720px))}.neu-dialog__panel--xl{width:min(100%,var(--neu-dialog-width-xl, 900px))}.neu-dialog__panel--full{width:min(100%,var(--neu-dialog-width-full, 1120px))}@media(max-width:640px){:where(.neu-dialog-panel--responsive){width:min(100vw - max(24px,env(safe-area-inset-left)) - max(24px,env(safe-area-inset-right)),var(--neu-dialog-width-full, 1120px));max-width:none;--neu-dialog-max-height: calc(100vh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(.neu-dialog-panel--responsive.neu-dialog-panel--layout-viewport){--neu-dialog-height: calc(100vh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(neu-dialog.neu-dialog--responsive){--neu-dialog-inset: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));--neu-dialog-margin: auto}:where(neu-dialog.neu-dialog--responsive.neu-dialog--layout-viewport){--neu-dialog-height: calc(100vh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) ;--neu-dialog-max-height: calc(100vh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) }@supports (height: 100dvh){:where(.neu-dialog-panel--responsive){--neu-dialog-max-height: calc(100dvh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(.neu-dialog-panel--responsive.neu-dialog-panel--layout-viewport){--neu-dialog-height: calc(100dvh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(neu-dialog.neu-dialog--responsive.neu-dialog--layout-viewport){--neu-dialog-height: calc(100dvh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) ;--neu-dialog-max-height: calc(100dvh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) }}}.neu-dialog__header{display:flex;align-items:center;justify-content:space-between;padding:var(--neu-space-4, 1rem) var(--neu-space-5, 1.25rem);border-bottom:1px solid var(--neu-border);gap:var(--neu-space-3, .75rem);flex-shrink:0}.neu-dialog__title{margin:0;font-size:var(--neu-text-lg, 1.125rem);font-weight:600;color:var(--neu-text);line-height:1.3}.neu-dialog__close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;flex:none;border:1px solid var(--neu-border);border-radius:var(--neu-radius);background:transparent;color:var(--neu-text-muted);cursor:pointer;transition:all var(--neu-transition);flex-shrink:0;padding:0}.neu-dialog__close:hover{background:var(--neu-surface-2);color:var(--neu-text);border-color:var(--neu-border-hover)}.neu-dialog__body{min-height:0;max-height:var(--neu-dialog-body-max-height, none);padding:var(--neu-dialog-body-padding, var(--neu-space-5, 1.25rem));overflow-y:auto;flex:var(--neu-dialog-body-flex, 0 1 auto);-webkit-overflow-scrolling:touch;overscroll-behavior:contain;color:var(--neu-text);font-size:var(--neu-text-sm, .875rem);line-height:1.6}[neu-dialog-footer]{display:flex;align-items:center;justify-content:flex-end;gap:var(--neu-space-3, .75rem);flex-wrap:var(--neu-dialog-footer-wrap, nowrap);padding:var(--neu-dialog-footer-padding, var(--neu-space-4, 1rem) var(--neu-space-5, 1.25rem));border-top:1px solid var(--neu-border);flex-shrink:0}[neu-dialog-footer] :where(button,[role=button]){min-height:44px}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "decorative", "ariaLabel", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
152
158
|
}
|
|
153
159
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuDialogComponent, decorators: [{
|
|
154
160
|
type: Component,
|
|
155
161
|
args: [{ selector: 'neu-dialog', imports: [NeuIconComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
156
162
|
'[class.neu-dialog--open]': 'open()',
|
|
163
|
+
'[class.neu-dialog--responsive]': 'responsive()',
|
|
164
|
+
'[class.neu-dialog--layout-auto]': 'layout() === "auto"',
|
|
165
|
+
'[class.neu-dialog--layout-viewport]': 'layout() === "viewport"',
|
|
157
166
|
'[attr.aria-hidden]': '!open()',
|
|
158
167
|
}, template: `
|
|
159
168
|
@if (open()) {
|
|
@@ -164,52 +173,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
164
173
|
aria-hidden="true"
|
|
165
174
|
></div>
|
|
166
175
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
176
|
+
<div class="neu-dialog__viewport">
|
|
177
|
+
<!-- Panel -->
|
|
178
|
+
<div
|
|
179
|
+
#panel
|
|
180
|
+
class="neu-dialog__panel neu-dialog__panel--{{ size() }}"
|
|
181
|
+
[class.neu-dialog__panel--responsive]="responsive()"
|
|
182
|
+
[class.neu-dialog__panel--layout-auto]="layout() === 'auto'"
|
|
183
|
+
[class.neu-dialog__panel--layout-viewport]="layout() === 'viewport'"
|
|
184
|
+
role="dialog"
|
|
185
|
+
tabindex="-1"
|
|
186
|
+
[id]="'neu-dialog-' + _uid"
|
|
187
|
+
[attr.aria-labelledby]="'neu-dialog-title-' + _uid"
|
|
188
|
+
[attr.aria-modal]="true"
|
|
189
|
+
(keydown)="onPanelKeydown($event)"
|
|
190
|
+
>
|
|
191
|
+
<!-- Header -->
|
|
192
|
+
<div class="neu-dialog__header">
|
|
193
|
+
<h2 class="neu-dialog__title" [id]="'neu-dialog-title-' + _uid">{{ title() }}</h2>
|
|
194
|
+
@if (!disableClose()) {
|
|
195
|
+
<button
|
|
196
|
+
class="neu-dialog__close"
|
|
197
|
+
type="button"
|
|
198
|
+
aria-label="Close dialog"
|
|
199
|
+
(click)="close()"
|
|
200
|
+
>
|
|
201
|
+
<neu-icon name="lucideX" size="1.125rem" />
|
|
202
|
+
</button>
|
|
203
|
+
}
|
|
204
|
+
</div>
|
|
193
205
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
<!-- Body -->
|
|
207
|
+
<div class="neu-dialog__body">
|
|
208
|
+
<ng-content />
|
|
209
|
+
</div>
|
|
198
210
|
|
|
199
|
-
|
|
200
|
-
|
|
211
|
+
<!-- Footer (opcional via slot) -->
|
|
212
|
+
<ng-content select="[neu-dialog-footer]" />
|
|
213
|
+
</div>
|
|
201
214
|
</div>
|
|
202
215
|
}
|
|
203
|
-
`, styles: [".neu-dialog-backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}@keyframes neu-backdrop-in{0%{opacity:0}to{opacity:1}}.neu-dialog-panel{background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);outline:none;display:flex;flex-direction:column;max-height:
|
|
204
|
-
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disableClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableClose", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], restoreFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocus", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], panelRef: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }] } });
|
|
216
|
+
`, styles: [".neu-dialog-backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}@keyframes neu-backdrop-in{0%{opacity:0}to{opacity:1}}.neu-dialog-panel{background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);outline:none;display:flex;flex-direction:column;width:min(100vw - 2rem,var(--neu-dialog-width-md, 560px));height:var(--neu-dialog-height, auto);max-height:var(--neu-dialog-max-height, 90vh);margin:var(--neu-dialog-margin, auto);overflow:hidden;animation:neu-dialog-in .2s cubic-bezier(.22,1,.36,1) both}.neu-dialog-panel--sm{width:min(100vw - 2rem,var(--neu-dialog-width-sm, 400px))}.neu-dialog-panel--md{width:min(100vw - 2rem,var(--neu-dialog-width-md, 560px))}.neu-dialog-panel--lg{width:min(100vw - 2rem,var(--neu-dialog-width-lg, 720px))}.neu-dialog-panel--xl{width:min(100vw - 2rem,var(--neu-dialog-width-xl, 900px))}.neu-dialog-panel--full{width:min(100vw - 2rem,var(--neu-dialog-width-full, 1120px))}:where(.neu-dialog-panel--layout-viewport){--neu-dialog-height: 90vh;--neu-dialog-body-flex: 1 1 auto}@keyframes neu-dialog-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}neu-dialog{display:contents}:where(neu-dialog.neu-dialog--layout-viewport){--neu-dialog-height: 90vh;--neu-dialog-body-flex: 1 1 auto}@supports (height: 100dvh){:where(neu-dialog),:where(.neu-dialog-panel){--neu-dialog-max-height: 90dvh}:where(neu-dialog.neu-dialog--layout-viewport),:where(.neu-dialog-panel--layout-viewport){--neu-dialog-height: 90dvh}}.neu-dialog__backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}.neu-dialog__viewport{position:fixed;inset:var(--neu-dialog-inset, 0);z-index:var(--neu-z-modal, 200);display:flex;align-items:center;justify-content:center;pointer-events:none;min-width:0;min-height:0}.neu-dialog__panel{position:relative;margin:var(--neu-dialog-margin, auto);background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);display:flex;flex-direction:column;height:var(--neu-dialog-height, auto);max-height:var(--neu-dialog-max-height, 90vh);max-width:100%;overflow:hidden;pointer-events:auto;animation:neu-dialog-in .2s cubic-bezier(.22,1,.36,1) both}.neu-dialog__panel--sm{width:min(100%,var(--neu-dialog-width-sm, 400px))}.neu-dialog__panel--md{width:min(100%,var(--neu-dialog-width-md, 560px))}.neu-dialog__panel--lg{width:min(100%,var(--neu-dialog-width-lg, 720px))}.neu-dialog__panel--xl{width:min(100%,var(--neu-dialog-width-xl, 900px))}.neu-dialog__panel--full{width:min(100%,var(--neu-dialog-width-full, 1120px))}@media(max-width:640px){:where(.neu-dialog-panel--responsive){width:min(100vw - max(24px,env(safe-area-inset-left)) - max(24px,env(safe-area-inset-right)),var(--neu-dialog-width-full, 1120px));max-width:none;--neu-dialog-max-height: calc(100vh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(.neu-dialog-panel--responsive.neu-dialog-panel--layout-viewport){--neu-dialog-height: calc(100vh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(neu-dialog.neu-dialog--responsive){--neu-dialog-inset: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));--neu-dialog-margin: auto}:where(neu-dialog.neu-dialog--responsive.neu-dialog--layout-viewport){--neu-dialog-height: calc(100vh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) ;--neu-dialog-max-height: calc(100vh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) }@supports (height: 100dvh){:where(.neu-dialog-panel--responsive){--neu-dialog-max-height: calc(100dvh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(.neu-dialog-panel--responsive.neu-dialog-panel--layout-viewport){--neu-dialog-height: calc(100dvh - max(24px, env(safe-area-inset-top)) - max(24px, env(safe-area-inset-bottom))) }:where(neu-dialog.neu-dialog--responsive.neu-dialog--layout-viewport){--neu-dialog-height: calc(100dvh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) ;--neu-dialog-max-height: calc(100dvh - max(12px, env(safe-area-inset-top)) - max(12px, env(safe-area-inset-bottom))) }}}.neu-dialog__header{display:flex;align-items:center;justify-content:space-between;padding:var(--neu-space-4, 1rem) var(--neu-space-5, 1.25rem);border-bottom:1px solid var(--neu-border);gap:var(--neu-space-3, .75rem);flex-shrink:0}.neu-dialog__title{margin:0;font-size:var(--neu-text-lg, 1.125rem);font-weight:600;color:var(--neu-text);line-height:1.3}.neu-dialog__close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;flex:none;border:1px solid var(--neu-border);border-radius:var(--neu-radius);background:transparent;color:var(--neu-text-muted);cursor:pointer;transition:all var(--neu-transition);flex-shrink:0;padding:0}.neu-dialog__close:hover{background:var(--neu-surface-2);color:var(--neu-text);border-color:var(--neu-border-hover)}.neu-dialog__body{min-height:0;max-height:var(--neu-dialog-body-max-height, none);padding:var(--neu-dialog-body-padding, var(--neu-space-5, 1.25rem));overflow-y:auto;flex:var(--neu-dialog-body-flex, 0 1 auto);-webkit-overflow-scrolling:touch;overscroll-behavior:contain;color:var(--neu-text);font-size:var(--neu-text-sm, .875rem);line-height:1.6}[neu-dialog-footer]{display:flex;align-items:center;justify-content:flex-end;gap:var(--neu-space-3, .75rem);flex-wrap:var(--neu-dialog-footer-wrap, nowrap);padding:var(--neu-dialog-footer-padding, var(--neu-space-4, 1rem) var(--neu-space-5, 1.25rem));border-top:1px solid var(--neu-border);flex-shrink:0}[neu-dialog-footer] :where(button,[role=button]){min-height:44px}\n"] }]
|
|
217
|
+
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], disableClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableClose", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], restoreFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "restoreFocus", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], panelRef: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }] } });
|
|
205
218
|
|
|
206
219
|
class NeuDialogService {
|
|
207
220
|
dialog = inject(Dialog);
|
|
208
221
|
open(component, config) {
|
|
209
222
|
return this.dialog.open(component, {
|
|
210
223
|
data: { title: config?.title, data: config?.data },
|
|
211
|
-
panelClass: [
|
|
224
|
+
panelClass: [
|
|
225
|
+
'neu-dialog-panel',
|
|
226
|
+
`neu-dialog-panel--${config?.size ?? 'md'}`,
|
|
227
|
+
`neu-dialog-panel--layout-${config?.layout ?? 'auto'}`,
|
|
228
|
+
...(config?.responsive ?? true ? ['neu-dialog-panel--responsive'] : []),
|
|
229
|
+
],
|
|
212
230
|
backdropClass: 'neu-dialog-backdrop',
|
|
231
|
+
maxWidth: 'none',
|
|
213
232
|
disableClose: config?.disableClose ?? false,
|
|
214
233
|
restoreFocus: config?.restoreFocus ?? true,
|
|
215
234
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-modal.mjs","sources":["../../../../projects/ui-core/modal/neu-modal.component.ts","../../../../projects/ui-core/modal/neu-dialog.service.ts","../../../../projects/ui-core/modal/neural-ui-core-modal.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n effect,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nexport type NeuDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\n\n/**\n * NeuDialogComponent — Diálogo accesible con header, body y footer. / Accessible dialog with header, body and footer.\n * Úsalo directamente como componente declarativo pasando `open` como signal. / Use it directly as a declarative component passing `open` as a signal.\n *\n * Para uso programático, utiliza NeuDialogService.open().\n *\n * Uso declarativo:\n * <neu-dialog [open]=\"isOpen()\" title=\"Editar usuario\" (closed)=\"isOpen.set(false)\">\n * <p>Contenido del diálogo</p>\n * <div neu-dialog-footer>\n * <neu-button (click)=\"save()\">Guardar</neu-button>\n * </div>\n * </neu-dialog>\n */\n@Component({\n selector: 'neu-dialog',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-dialog--open]': 'open()',\n '[attr.aria-hidden]': '!open()',\n },\n template: `\n @if (open()) {\n <!-- Backdrop -->\n <div\n class=\"neu-dialog__backdrop\"\n (click)=\"!disableClose() && close()\"\n aria-hidden=\"true\"\n ></div>\n\n <!-- Panel -->\n <div\n #panel\n class=\"neu-dialog__panel neu-dialog__panel--{{ size() }}\"\n [class.neu-dialog__panel--responsive]=\"responsive()\"\n role=\"dialog\"\n tabindex=\"-1\"\n [id]=\"'neu-dialog-' + _uid\"\n [attr.aria-labelledby]=\"'neu-dialog-title-' + _uid\"\n [attr.aria-modal]=\"true\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <!-- Header -->\n <div class=\"neu-dialog__header\">\n <h2 class=\"neu-dialog__title\" [id]=\"'neu-dialog-title-' + _uid\">{{ title() }}</h2>\n @if (!disableClose()) {\n <button\n class=\"neu-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n <neu-icon name=\"lucideX\" size=\"1.125rem\" />\n </button>\n }\n </div>\n\n <!-- Body -->\n <div class=\"neu-dialog__body\">\n <ng-content />\n </div>\n\n <!-- Footer (opcional via slot) -->\n <ng-content select=\"[neu-dialog-footer]\" />\n </div>\n }\n `,\n styleUrl: './neu-modal.component.scss',\n})\nexport class NeuDialogComponent {\n /** Controla la visibilidad del diálogo. / Controls dialog visibility. */\n open = input<boolean>(false);\n /** Título que aparece en el header. / Title shown in the header. */\n title = input<string>('');\n /** Tamaño del panel: sm | md | lg | xl | full. / Panel size: sm | md | lg | xl | full. */\n size = input<NeuDialogSize>('md');\n /** Si es true, el backdrop y el botón cerrar no funcionan. / If true, the backdrop and close button do not work. */\n disableClose = input<boolean>(false);\n /** Adapta el panel a mobile/full-width cuando el viewport es estrecho. */\n responsive = input<boolean>(true);\n /** Devuelve el foco al elemento activo antes de abrir. */\n restoreFocus = input<boolean>(true);\n\n /** Emite cuando el usuario cierra el diálogo. / Emits when the user closes the dialog. */\n closed = output<unknown>();\n\n private readonly panelRef = viewChild<ElementRef<HTMLElement>>('panel');\n private previousActiveElement: HTMLElement | null = null;\n\n /** @internal — ID único para aria-labelledby / Unique ID for aria-labelledby */\n readonly _uid = Math.random().toString(36).slice(2, 7);\n\n constructor() {\n effect(() => {\n if (!this.open()) {\n this.restorePreviousFocus();\n return;\n }\n\n this.previousActiveElement = document.activeElement as HTMLElement | null;\n queueMicrotask(() => this.focusInitialElement());\n });\n }\n\n close(result?: unknown): void {\n this.closed.emit(result);\n }\n\n onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n if (!this.disableClose()) {\n this.close();\n }\n return;\n }\n\n if (event.key !== 'Tab') return;\n\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const focusable = this.getFocusableElements(panel);\n if (!focusable.length) {\n event.preventDefault();\n panel.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey) {\n if (activeElement === first || activeElement === panel) {\n event.preventDefault();\n last.focus();\n }\n return;\n }\n\n if (activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n }\n\n private focusInitialElement(): void {\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const [firstFocusable] = this.getFocusableElements(panel);\n (firstFocusable ?? panel).focus();\n }\n\n private restorePreviousFocus(): void {\n if (!this.restoreFocus() || !this.previousActiveElement?.focus) {\n this.previousActiveElement = null;\n return;\n }\n\n queueMicrotask(() => {\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n });\n }\n\n private getFocusableElements(panel: HTMLElement): HTMLElement[] {\n return Array.from(\n panel.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ).filter((element) => !element.hasAttribute('aria-hidden'));\n }\n}\n","import { Injectable, Type, inject } from '@angular/core';\nimport { Dialog, DialogConfig, DialogRef } from '@angular/cdk/dialog';\nimport { NeuDialogSize } from './neu-modal.component';\n\n/** Datos que se inyectan en el componente del diálogo / Data injected into the dialog component */\nexport interface NeuDialogData<T = unknown> {\n title?: string;\n data?: T;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class NeuDialogService {\n private readonly dialog = inject(Dialog);\n\n open<T = unknown, R = unknown>(\n component: Type<unknown>,\n config?: {\n title?: string;\n data?: T;\n size?: NeuDialogSize;\n disableClose?: boolean;\n restoreFocus?: boolean;\n },\n ): DialogRef<R> {\n return this.dialog.open<R>(component, {\n data: { title: config?.title, data: config?.data } satisfies NeuDialogData<T>,\n panelClass: ['neu-dialog-panel', `neu-dialog-panel--${config?.size ?? 'md'}`],\n backdropClass: 'neu-dialog-backdrop',\n disableClose: config?.disableClose ?? false,\n restoreFocus: config?.restoreFocus ?? true,\n } satisfies DialogConfig);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;AAcA;;;;;;;;;;;;;AAaG;MA0DU,kBAAkB,CAAA;;AAE7B,IAAA,IAAI,GAAG,KAAK,CAAU,KAAK,2EAAC;;AAE5B,IAAA,KAAK,GAAG,KAAK,CAAS,EAAE,4EAAC;;AAEzB,IAAA,IAAI,GAAG,KAAK,CAAgB,IAAI,2EAAC;;AAEjC,IAAA,YAAY,GAAG,KAAK,CAAU,KAAK,mFAAC;;AAEpC,IAAA,UAAU,GAAG,KAAK,CAAU,IAAI,iFAAC;;AAEjC,IAAA,YAAY,GAAG,KAAK,CAAU,IAAI,mFAAC;;IAGnC,MAAM,GAAG,MAAM,EAAW;AAET,IAAA,QAAQ,GAAG,SAAS,CAA0B,OAAO,+EAAC;IAC/D,qBAAqB,GAAuB,IAAI;;AAG/C,IAAA,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AAEtD,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE;gBAChB,IAAI,CAAC,oBAAoB,EAAE;gBAC3B;YACF;AAEA,YAAA,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC,aAAmC;YACzE,cAAc,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;AAClD,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,KAAK,CAAC,MAAgB,EAAA;AACpB,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B;AAEA,IAAA,cAAc,CAAC,KAAoB,EAAA;AACjC,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;AAC1B,YAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;gBACxB,IAAI,CAAC,KAAK,EAAE;YACd;YACA;QACF;AAEA,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK;YAAE;QAEzB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,aAAa;AAC5C,QAAA,IAAI,CAAC,KAAK;YAAE;QAEZ,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;AAClD,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;YACrB,KAAK,CAAC,cAAc,EAAE;YACtB,KAAK,CAAC,KAAK,EAAE;YACb;QACF;AAEA,QAAA,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5C,QAAA,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAmC;AAElE,QAAA,IAAI,KAAK,CAAC,QAAQ,EAAE;YAClB,IAAI,aAAa,KAAK,KAAK,IAAI,aAAa,KAAK,KAAK,EAAE;gBACtD,KAAK,CAAC,cAAc,EAAE;gBACtB,IAAI,CAAC,KAAK,EAAE;YACd;YACA;QACF;AAEA,QAAA,IAAI,aAAa,KAAK,IAAI,EAAE;YAC1B,KAAK,CAAC,cAAc,EAAE;YACtB,KAAK,CAAC,KAAK,EAAE;QACf;IACF;IAEQ,mBAAmB,GAAA;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,aAAa;AAC5C,QAAA,IAAI,CAAC,KAAK;YAAE;QAEZ,MAAM,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;AACzD,QAAA,CAAC,cAAc,IAAI,KAAK,EAAE,KAAK,EAAE;IACnC;IAEQ,oBAAoB,GAAA;AAC1B,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE;AAC9D,YAAA,IAAI,CAAC,qBAAqB,GAAG,IAAI;YACjC;QACF;QAEA,cAAc,CAAC,MAAK;AAClB,YAAA,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE;AACnC,YAAA,IAAI,CAAC,qBAAqB,GAAG,IAAI;AACnC,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,oBAAoB,CAAC,KAAkB,EAAA;QAC7C,OAAO,KAAK,CAAC,IAAI,CACf,KAAK,CAAC,gBAAgB,CACpB,0IAA0I,CAC3I,CACF,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;IAC7D;wGAvGW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,SAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,UAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,OAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhDnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,6kGAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EApDS,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,WAAA,EAAA,aAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;4FAuDf,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAzD9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,EAAA,OAAA,EACb,CAAC,gBAAgB,CAAC,EAAA,aAAA,EACZ,iBAAiB,CAAC,IAAI,EAAA,eAAA,EACpB,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,0BAA0B,EAAE,QAAQ;AACpC,wBAAA,oBAAoB,EAAE,SAAS;qBAChC,EAAA,QAAA,EACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,6kGAAA,CAAA,EAAA;+sBAoB8D,OAAO,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;MC3F3D,gBAAgB,CAAA;AACV,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAExC,IAAI,CACF,SAAwB,EACxB,MAMC,EAAA;AAED,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAI,SAAS,EAAE;AACpC,YAAA,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAA6B;YAC7E,UAAU,EAAE,CAAC,kBAAkB,EAAE,CAAA,kBAAA,EAAqB,MAAM,EAAE,IAAI,IAAI,IAAI,CAAA,CAAE,CAAC;AAC7E,YAAA,aAAa,EAAE,qBAAqB;AACpC,YAAA,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,KAAK;AAC3C,YAAA,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,IAAI;AACpB,SAAA,CAAC;IAC3B;wGApBW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cADH,MAAM,EAAA,CAAA;;4FACnB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACVlC;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"neural-ui-core-modal.mjs","sources":["../../../../projects/ui-core/modal/neu-modal.component.ts","../../../../projects/ui-core/modal/neu-dialog.service.ts","../../../../projects/ui-core/modal/neural-ui-core-modal.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n effect,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nexport type NeuDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\nexport type NeuDialogLayout = 'auto' | 'viewport';\n\n/**\n * NeuDialogComponent — Diálogo accesible con header, body y footer. / Accessible dialog with header, body and footer.\n * Úsalo directamente como componente declarativo pasando `open` como signal. / Use it directly as a declarative component passing `open` as a signal.\n *\n * Para uso programático, utiliza NeuDialogService.open().\n *\n * Uso declarativo:\n * <neu-dialog [open]=\"isOpen()\" title=\"Editar usuario\" (closed)=\"isOpen.set(false)\">\n * <p>Contenido del diálogo</p>\n * <div neu-dialog-footer>\n * <neu-button (click)=\"save()\">Guardar</neu-button>\n * </div>\n * </neu-dialog>\n */\n@Component({\n selector: 'neu-dialog',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-dialog--open]': 'open()',\n '[class.neu-dialog--responsive]': 'responsive()',\n '[class.neu-dialog--layout-auto]': 'layout() === \"auto\"',\n '[class.neu-dialog--layout-viewport]': 'layout() === \"viewport\"',\n '[attr.aria-hidden]': '!open()',\n },\n template: `\n @if (open()) {\n <!-- Backdrop -->\n <div\n class=\"neu-dialog__backdrop\"\n (click)=\"!disableClose() && close()\"\n aria-hidden=\"true\"\n ></div>\n\n <div class=\"neu-dialog__viewport\">\n <!-- Panel -->\n <div\n #panel\n class=\"neu-dialog__panel neu-dialog__panel--{{ size() }}\"\n [class.neu-dialog__panel--responsive]=\"responsive()\"\n [class.neu-dialog__panel--layout-auto]=\"layout() === 'auto'\"\n [class.neu-dialog__panel--layout-viewport]=\"layout() === 'viewport'\"\n role=\"dialog\"\n tabindex=\"-1\"\n [id]=\"'neu-dialog-' + _uid\"\n [attr.aria-labelledby]=\"'neu-dialog-title-' + _uid\"\n [attr.aria-modal]=\"true\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <!-- Header -->\n <div class=\"neu-dialog__header\">\n <h2 class=\"neu-dialog__title\" [id]=\"'neu-dialog-title-' + _uid\">{{ title() }}</h2>\n @if (!disableClose()) {\n <button\n class=\"neu-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"close()\"\n >\n <neu-icon name=\"lucideX\" size=\"1.125rem\" />\n </button>\n }\n </div>\n\n <!-- Body -->\n <div class=\"neu-dialog__body\">\n <ng-content />\n </div>\n\n <!-- Footer (opcional via slot) -->\n <ng-content select=\"[neu-dialog-footer]\" />\n </div>\n </div>\n }\n `,\n styleUrl: './neu-modal.component.scss',\n})\nexport class NeuDialogComponent {\n /** Controla la visibilidad del diálogo. / Controls dialog visibility. */\n open = input<boolean>(false);\n /** Título que aparece en el header. / Title shown in the header. */\n title = input<string>('');\n /** Tamaño del panel: sm | md | lg | xl | full. / Panel size: sm | md | lg | xl | full. */\n size = input<NeuDialogSize>('md');\n /** Ajusta la altura al contenido o al viewport disponible. / Fits height to content or to the available viewport. */\n layout = input<NeuDialogLayout>('auto');\n /** Si es true, el backdrop y el botón cerrar no funcionan. / If true, the backdrop and close button do not work. */\n disableClose = input<boolean>(false);\n /** Adapta el panel a mobile/full-width cuando el viewport es estrecho. */\n responsive = input<boolean>(true);\n /** Devuelve el foco al elemento activo antes de abrir. */\n restoreFocus = input<boolean>(true);\n\n /** Emite cuando el usuario cierra el diálogo. / Emits when the user closes the dialog. */\n closed = output<unknown>();\n\n private readonly panelRef = viewChild<ElementRef<HTMLElement>>('panel');\n private previousActiveElement: HTMLElement | null = null;\n\n /** @internal — ID único para aria-labelledby / Unique ID for aria-labelledby */\n readonly _uid = Math.random().toString(36).slice(2, 7);\n\n constructor() {\n effect(() => {\n if (!this.open()) {\n this.restorePreviousFocus();\n return;\n }\n\n this.previousActiveElement = document.activeElement as HTMLElement | null;\n queueMicrotask(() => this.focusInitialElement());\n });\n }\n\n close(result?: unknown): void {\n this.closed.emit(result);\n }\n\n onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n if (!this.disableClose()) {\n this.close();\n }\n return;\n }\n\n if (event.key !== 'Tab') return;\n\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const focusable = this.getFocusableElements(panel);\n if (!focusable.length) {\n event.preventDefault();\n panel.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey) {\n if (activeElement === first || activeElement === panel) {\n event.preventDefault();\n last.focus();\n }\n return;\n }\n\n if (activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n }\n\n private focusInitialElement(): void {\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const [firstFocusable] = this.getFocusableElements(panel);\n (firstFocusable ?? panel).focus();\n }\n\n private restorePreviousFocus(): void {\n if (!this.restoreFocus() || !this.previousActiveElement?.focus) {\n this.previousActiveElement = null;\n return;\n }\n\n queueMicrotask(() => {\n this.previousActiveElement?.focus();\n this.previousActiveElement = null;\n });\n }\n\n private getFocusableElements(panel: HTMLElement): HTMLElement[] {\n return Array.from(\n panel.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ).filter((element) => !element.hasAttribute('aria-hidden'));\n }\n}\n","import { Injectable, Type, inject } from '@angular/core';\nimport { Dialog, DialogConfig, DialogRef } from '@angular/cdk/dialog';\nimport { NeuDialogLayout, NeuDialogSize } from './neu-modal.component';\n\n/** Datos que se inyectan en el componente del diálogo / Data injected into the dialog component */\nexport interface NeuDialogData<T = unknown> {\n title?: string;\n data?: T;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class NeuDialogService {\n private readonly dialog = inject(Dialog);\n\n open<T = unknown, R = unknown>(\n component: Type<unknown>,\n config?: {\n title?: string;\n data?: T;\n size?: NeuDialogSize;\n layout?: NeuDialogLayout;\n responsive?: boolean;\n disableClose?: boolean;\n restoreFocus?: boolean;\n },\n ): DialogRef<R> {\n return this.dialog.open<R>(component, {\n data: { title: config?.title, data: config?.data } satisfies NeuDialogData<T>,\n panelClass: [\n 'neu-dialog-panel',\n `neu-dialog-panel--${config?.size ?? 'md'}`,\n `neu-dialog-panel--layout-${config?.layout ?? 'auto'}`,\n ...(config?.responsive ?? true ? ['neu-dialog-panel--responsive'] : []),\n ],\n backdropClass: 'neu-dialog-backdrop',\n maxWidth: 'none',\n disableClose: config?.disableClose ?? false,\n restoreFocus: config?.restoreFocus ?? true,\n } satisfies DialogConfig);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/styles/_tokens.scss
CHANGED
|
@@ -124,6 +124,22 @@
|
|
|
124
124
|
--neu-sidebar-width: 260px;
|
|
125
125
|
--neu-sidebar-bg: var(--neu-surface);
|
|
126
126
|
|
|
127
|
+
// Dialog — layout configurable without piercing component encapsulation
|
|
128
|
+
--neu-dialog-height: auto;
|
|
129
|
+
--neu-dialog-max-height: 90vh;
|
|
130
|
+
--neu-dialog-inset: 0;
|
|
131
|
+
--neu-dialog-margin: auto;
|
|
132
|
+
--neu-dialog-body-flex: 0 1 auto;
|
|
133
|
+
--neu-dialog-body-max-height: none;
|
|
134
|
+
--neu-dialog-body-padding: var(--neu-space-5);
|
|
135
|
+
--neu-dialog-footer-padding: var(--neu-space-4) var(--neu-space-5);
|
|
136
|
+
--neu-dialog-footer-wrap: nowrap;
|
|
137
|
+
--neu-dialog-width-sm: 400px;
|
|
138
|
+
--neu-dialog-width-md: 560px;
|
|
139
|
+
--neu-dialog-width-lg: 720px;
|
|
140
|
+
--neu-dialog-width-xl: 900px;
|
|
141
|
+
--neu-dialog-width-full: 1120px;
|
|
142
|
+
|
|
127
143
|
// ------------------------------------------------
|
|
128
144
|
// Z-index
|
|
129
145
|
// ------------------------------------------------
|
|
@@ -3,6 +3,7 @@ import { Type } from '@angular/core';
|
|
|
3
3
|
import { DialogRef } from '@angular/cdk/dialog';
|
|
4
4
|
|
|
5
5
|
type NeuDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
6
|
+
type NeuDialogLayout = 'auto' | 'viewport';
|
|
6
7
|
/**
|
|
7
8
|
* NeuDialogComponent — Diálogo accesible con header, body y footer. / Accessible dialog with header, body and footer.
|
|
8
9
|
* Úsalo directamente como componente declarativo pasando `open` como signal. / Use it directly as a declarative component passing `open` as a signal.
|
|
@@ -24,6 +25,8 @@ declare class NeuDialogComponent {
|
|
|
24
25
|
title: _angular_core.InputSignal<string>;
|
|
25
26
|
/** Tamaño del panel: sm | md | lg | xl | full. / Panel size: sm | md | lg | xl | full. */
|
|
26
27
|
size: _angular_core.InputSignal<NeuDialogSize>;
|
|
28
|
+
/** Ajusta la altura al contenido o al viewport disponible. / Fits height to content or to the available viewport. */
|
|
29
|
+
layout: _angular_core.InputSignal<NeuDialogLayout>;
|
|
27
30
|
/** Si es true, el backdrop y el botón cerrar no funcionan. / If true, the backdrop and close button do not work. */
|
|
28
31
|
disableClose: _angular_core.InputSignal<boolean>;
|
|
29
32
|
/** Adapta el panel a mobile/full-width cuando el viewport es estrecho. */
|
|
@@ -43,7 +46,7 @@ declare class NeuDialogComponent {
|
|
|
43
46
|
private restorePreviousFocus;
|
|
44
47
|
private getFocusableElements;
|
|
45
48
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NeuDialogComponent, never>;
|
|
46
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuDialogComponent, "neu-dialog", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "disableClose": { "alias": "disableClose"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "restoreFocus": { "alias": "restoreFocus"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, never, ["*", "[neu-dialog-footer]"], true, never>;
|
|
49
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NeuDialogComponent, "neu-dialog", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "disableClose": { "alias": "disableClose"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "restoreFocus": { "alias": "restoreFocus"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, never, ["*", "[neu-dialog-footer]"], true, never>;
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
/** Datos que se inyectan en el componente del diálogo / Data injected into the dialog component */
|
|
@@ -57,6 +60,8 @@ declare class NeuDialogService {
|
|
|
57
60
|
title?: string;
|
|
58
61
|
data?: T;
|
|
59
62
|
size?: NeuDialogSize;
|
|
63
|
+
layout?: NeuDialogLayout;
|
|
64
|
+
responsive?: boolean;
|
|
60
65
|
disableClose?: boolean;
|
|
61
66
|
restoreFocus?: boolean;
|
|
62
67
|
}): DialogRef<R>;
|
|
@@ -65,4 +70,4 @@ declare class NeuDialogService {
|
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
export { NeuDialogComponent, NeuDialogService };
|
|
68
|
-
export type { NeuDialogData, NeuDialogSize };
|
|
73
|
+
export type { NeuDialogData, NeuDialogLayout, NeuDialogSize };
|