mn-angular-lib 1.0.24 → 1.0.26
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.
|
@@ -1504,6 +1504,10 @@ class MnInputField {
|
|
|
1504
1504
|
if (typeof msgDef === 'function') {
|
|
1505
1505
|
return msgDef(errorArgs, errors);
|
|
1506
1506
|
}
|
|
1507
|
+
// Interpolate {{placeholder}} tokens with error arguments (e.g. {{requiredLength}})
|
|
1508
|
+
if (errorArgs && typeof errorArgs === 'object') {
|
|
1509
|
+
return msgDef.replace(/\{\{(\w+)\}\}/g, (_, key) => errorArgs[key] !== undefined ? String(errorArgs[key]) : `{{${key}}}`);
|
|
1510
|
+
}
|
|
1507
1511
|
return msgDef;
|
|
1508
1512
|
}
|
|
1509
1513
|
/**
|
|
@@ -3473,6 +3477,13 @@ class WizardModalBuilder extends BaseModalBuilder {
|
|
|
3473
3477
|
this.config.initialValue = value;
|
|
3474
3478
|
return this;
|
|
3475
3479
|
}
|
|
3480
|
+
/**
|
|
3481
|
+
* Description is not supported for wizard modals.
|
|
3482
|
+
* Use step-level body text instead.
|
|
3483
|
+
*/
|
|
3484
|
+
description(_description) {
|
|
3485
|
+
return this;
|
|
3486
|
+
}
|
|
3476
3487
|
body(body) {
|
|
3477
3488
|
return super.body(body);
|
|
3478
3489
|
}
|
|
@@ -4382,6 +4393,8 @@ class MnFormBodyComponent {
|
|
|
4382
4393
|
formErrors = {};
|
|
4383
4394
|
/** Track which fields are currently visible (for conditional fields) */
|
|
4384
4395
|
fieldVisibility = {};
|
|
4396
|
+
/** Track which fields are currently conditionally required */
|
|
4397
|
+
fieldConditionallyRequired = {};
|
|
4385
4398
|
/** Track loading state per field for async data sources */
|
|
4386
4399
|
fieldLoading = {};
|
|
4387
4400
|
/** Dynamic options loaded from data sources */
|
|
@@ -4400,6 +4413,12 @@ class MnFormBodyComponent {
|
|
|
4400
4413
|
return val;
|
|
4401
4414
|
}
|
|
4402
4415
|
hasRequiredValidator(field) {
|
|
4416
|
+
// Check if conditionallyRequired is currently active
|
|
4417
|
+
if (field.conditionallyRequired) {
|
|
4418
|
+
const formValue = this.form?.value ?? {};
|
|
4419
|
+
if (field.conditionallyRequired(formValue))
|
|
4420
|
+
return true;
|
|
4421
|
+
}
|
|
4403
4422
|
const validators = field.validators;
|
|
4404
4423
|
if (!validators)
|
|
4405
4424
|
return false;
|
|
@@ -4624,10 +4643,11 @@ class MnFormBodyComponent {
|
|
|
4624
4643
|
// Feature 1: Conditional/Dynamic Fields
|
|
4625
4644
|
// =========================
|
|
4626
4645
|
initializeVisibility() {
|
|
4646
|
+
const formValue = this.form.value;
|
|
4627
4647
|
this.config.fields.forEach(field => {
|
|
4628
4648
|
const key = field.key;
|
|
4629
4649
|
const fieldAny = field;
|
|
4630
|
-
const isVisible = fieldAny.visible ? fieldAny.visible(
|
|
4650
|
+
const isVisible = fieldAny.visible ? fieldAny.visible(formValue) : true;
|
|
4631
4651
|
this.fieldVisibility[key] = isVisible;
|
|
4632
4652
|
// If initially hidden, clear validators so they don't block submit
|
|
4633
4653
|
if (!isVisible) {
|
|
@@ -4637,6 +4657,19 @@ class MnFormBodyComponent {
|
|
|
4637
4657
|
control.updateValueAndValidity({ emitEvent: false });
|
|
4638
4658
|
}
|
|
4639
4659
|
}
|
|
4660
|
+
else if (fieldAny.conditionallyRequired) {
|
|
4661
|
+
// Initialize conditionallyRequired state for visible fields
|
|
4662
|
+
const isRequired = fieldAny.conditionallyRequired(formValue);
|
|
4663
|
+
this.fieldConditionallyRequired[key] = isRequired;
|
|
4664
|
+
if (isRequired) {
|
|
4665
|
+
const control = this.form.get(key);
|
|
4666
|
+
if (control) {
|
|
4667
|
+
const validators = this.buildValidators(fieldAny, formValue);
|
|
4668
|
+
control.setValidators(validators);
|
|
4669
|
+
control.updateValueAndValidity({ emitEvent: false });
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4640
4673
|
});
|
|
4641
4674
|
}
|
|
4642
4675
|
updateVisibility() {
|
|
@@ -4655,14 +4688,54 @@ class MnFormBodyComponent {
|
|
|
4655
4688
|
control.updateValueAndValidity({ emitEvent: false });
|
|
4656
4689
|
}
|
|
4657
4690
|
else if (isVisible && !wasVisible) {
|
|
4658
|
-
// Restore validators
|
|
4659
|
-
const validators = fieldAny
|
|
4691
|
+
// Restore validators (including conditionallyRequired if active)
|
|
4692
|
+
const validators = this.buildValidators(fieldAny, formValue);
|
|
4660
4693
|
control.setValidators(validators);
|
|
4661
4694
|
control.updateValueAndValidity({ emitEvent: false });
|
|
4662
4695
|
}
|
|
4696
|
+
else if (isVisible) {
|
|
4697
|
+
// Update conditionallyRequired for visible fields
|
|
4698
|
+
this.updateConditionallyRequired(fieldAny, formValue);
|
|
4699
|
+
}
|
|
4663
4700
|
}
|
|
4664
4701
|
});
|
|
4665
4702
|
}
|
|
4703
|
+
/**
|
|
4704
|
+
* Builds the full validator array for a field, including conditionallyRequired.
|
|
4705
|
+
* @param fieldAny The field configuration.
|
|
4706
|
+
* @param formValue The current form values.
|
|
4707
|
+
* @returns Array of validators to apply.
|
|
4708
|
+
*/
|
|
4709
|
+
buildValidators(fieldAny, formValue) {
|
|
4710
|
+
const baseValidators = fieldAny.validators ? [...fieldAny.validators] : [];
|
|
4711
|
+
if (fieldAny.conditionallyRequired && fieldAny.conditionallyRequired(formValue)) {
|
|
4712
|
+
if (!baseValidators.includes(Validators.required)) {
|
|
4713
|
+
baseValidators.push(Validators.required);
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4716
|
+
return baseValidators;
|
|
4717
|
+
}
|
|
4718
|
+
/**
|
|
4719
|
+
* Updates the conditionallyRequired state for a single field and adjusts validators.
|
|
4720
|
+
* @param fieldAny The field configuration.
|
|
4721
|
+
* @param formValue The current form values.
|
|
4722
|
+
*/
|
|
4723
|
+
updateConditionallyRequired(fieldAny, formValue) {
|
|
4724
|
+
if (!fieldAny.conditionallyRequired)
|
|
4725
|
+
return;
|
|
4726
|
+
const key = fieldAny.key;
|
|
4727
|
+
const wasRequired = this.fieldConditionallyRequired[key] ?? false;
|
|
4728
|
+
const isRequired = fieldAny.conditionallyRequired(formValue);
|
|
4729
|
+
this.fieldConditionallyRequired[key] = isRequired;
|
|
4730
|
+
if (isRequired !== wasRequired) {
|
|
4731
|
+
const control = this.form.get(key);
|
|
4732
|
+
if (control) {
|
|
4733
|
+
const validators = this.buildValidators(fieldAny, formValue);
|
|
4734
|
+
control.setValidators(validators);
|
|
4735
|
+
control.updateValueAndValidity({ emitEvent: false });
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
4738
|
+
}
|
|
4666
4739
|
isFieldVisible(field) {
|
|
4667
4740
|
return this.fieldVisibility[field.key];
|
|
4668
4741
|
}
|
|
@@ -5439,11 +5512,11 @@ class MnWizardBodyComponent {
|
|
|
5439
5512
|
}
|
|
5440
5513
|
}
|
|
5441
5514
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnWizardBodyComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5442
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnWizardBodyComponent, isStandalone: true, selector: "mn-wizard-body", inputs: { config: "config", modalRef: "modalRef" }, viewQueries: [{ propertyName: "formBodies", predicate: MnFormBodyComponent, descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-6\" [class.h-full]=\"config.sizeHeight\">\n @if (config.component || config.template) {\n <mn-custom-body-host\n [config]=\"asAny(config)\"\n [modalRef]=\"asAny(modalRef)\"\n class=\"block\"\n ></mn-custom-body-host>\n }\n\n <div class=\"
|
|
5515
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnWizardBodyComponent, isStandalone: true, selector: "mn-wizard-body", inputs: { config: "config", modalRef: "modalRef" }, viewQueries: [{ propertyName: "formBodies", predicate: MnFormBodyComponent, descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col gap-6\" [class.h-full]=\"config.sizeHeight\">\n @if (config.component || config.template) {\n <mn-custom-body-host\n [config]=\"asAny(config)\"\n [modalRef]=\"asAny(modalRef)\"\n class=\"block\"\n ></mn-custom-body-host>\n }\n\n <div class=\"pb-4 border-b border-base-300 -mx-6 px-6 -mt-4\">\n <div class=\"relative flex items-start\">\n <!-- Background line spanning from first circle center to last circle center -->\n <div\n [style.left]=\"'calc(' + 100 / (2 * visibleSteps.length) + '%)'\"\n [style.right]=\"'calc(' + 100 / (2 * visibleSteps.length) + '%)'\"\n class=\"absolute top-[15px] h-1 bg-base-300 z-0\"\n ></div>\n\n <!-- Progress fill line -->\n @if (visibleSteps.length > 1) {\n <div\n [style.left]=\"'calc(' + 100 / (2 * visibleSteps.length) + '%)'\"\n [style.width]=\"'calc(' + (currentProgressIndex / (visibleSteps.length - 1)) * (100 - 100 / visibleSteps.length) + '%)'\"\n class=\"absolute top-[15px] h-1 bg-success z-[1] transition-all duration-500\"\n ></div>\n }\n\n @for (step of visibleSteps; track step.id; let i = $index; let last = $last) {\n <div\n (click)=\"isFreeFlow ? goToStep(step) : null\"\n [class.cursor-pointer]=\"isFreeFlow && canNavigateToStep(step)\"\n class=\"relative flex flex-col items-center gap-1 z-10 w-0 flex-1\"\n >\n <div\n [ngClass]=\"{\n 'bg-primary text-primary-content': step.id === currentStepId,\n 'bg-success text-success-content': visitedStepIds.includes(step.id) && step.id !== currentStepId,\n 'bg-base-200 text-base-content/50': !visitedStepIds.includes(step.id) && step.id !== currentStepId\n }\"\n class=\"w-8 h-8 rounded-full flex items-center justify-center font-semibold transition-all text-sm\"\n >{{ i + 1 }}\n </div>\n <div\n [ngClass]=\"{\n 'text-base-content font-semibold': step.id === currentStepId,\n 'text-base-content/50': step.id !== currentStepId\n }\"\n class=\"text-xs text-center whitespace-nowrap\"\n >{{ step.title }}\n </div>\n\n </div>\n }\n </div>\n </div>\n\n <div class=\"min-h-48 flex-1\">\n @for (step of config.steps; track step.id) {\n <div [style.display]=\"step.id === currentStepId ? 'block' : 'none'\">\n <h3 class=\"text-lg font-semibold text-base-content mb-4\">{{ step.title }}</h3>\n <div class=\"text-base-content/80\">\n <!-- Form step -->\n @if (stepFormConfigs[step.id]) {\n <mn-form-body\n [config]=\"stepFormConfigs[step.id]\"\n [modalRef]=\"asAny(modalRef)\"\n [hideFooter]=\"true\"\n [hideCustomBody]=\"true\"\n ></mn-form-body>\n }\n\n <!-- Text body -->\n @if (!stepFormConfigs[step.id] && isTextBody(step)) {\n <div>\n {{ step.body }}\n </div>\n }\n\n <!-- Dynamic content container for component/template bodies -->\n <ng-container #dynamicContainer></ng-container>\n </div>\n </div>\n }\n </div>\n\n <!-- Wizard-level errors (from onBeforeComplete) -->\n @if (wizardErrors && (wizardErrors | keyvalue).length > 0) {\n <div class=\"flex flex-col gap-1 px-2 py-2 bg-red-50 rounded-md\">\n @for (err of wizardErrors | keyvalue; track err.key) {\n <div class=\"text-red-500 text-sm\">\n {{ err.value }}\n </div>\n }\n </div>\n }\n\n <div class=\"flex gap-3 pt-4 border-t border-base-300\">\n @if (!currentStep?.hideBack) {\n <button\n mnButton\n [data]=\"{ variant: 'outline', color: 'secondary' }\"\n (click)=\"back()\"\n >\n {{ currentStep?.backLabel || (canGoBack ? labels.back : labels.close) }}\n </button>\n }\n\n <!-- Custom footer actions -->\n @if (config.footerActions) {\n <mn-footer-actions\n [actions]=\"config.footerActions\"\n (actionClick)=\"handleFooterAction($event)\"\n ></mn-footer-actions>\n } @else {\n <div class=\"flex-1\"></div>\n }\n\n @if (!isLastStep) {\n <button\n mnButton\n [data]=\"{ variant: 'fill', color: 'primary', disabled: !isCurrentStepValid }\"\n (click)=\"next()\"\n >\n {{ currentStep?.nextLabel || labels.next }}\n </button>\n }\n\n @if (isLastStep) {\n <button\n mnButton\n [data]=\"{ variant: 'fill', color: 'primary', disabled: !isCurrentStepValid || isCompleting }\"\n [disabled]=\"!isCurrentStepValid || isCompleting\"\n (click)=\"complete()\"\n >\n {{ currentStep?.nextLabel || (isCompleting ? labels.completing : labels.complete) }}\n </button>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: MnButton, selector: "button[mnButton], a[mnButton]", inputs: ["data"] }, { kind: "component", type: MnFormBodyComponent, selector: "mn-form-body", inputs: ["config", "modalRef", "hideFooter", "hideCustomBody"], outputs: ["formStatusChange"] }, { kind: "component", type: MnCustomBodyHostComponent, selector: "mn-custom-body-host", inputs: ["config", "modalRef"] }, { kind: "component", type: MnFooterActionsComponent, selector: "mn-footer-actions", inputs: ["actions"], outputs: ["actionClick"] }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }] });
|
|
5443
5516
|
}
|
|
5444
5517
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnWizardBodyComponent, decorators: [{
|
|
5445
5518
|
type: Component,
|
|
5446
|
-
args: [{ selector: 'mn-wizard-body', standalone: true, imports: [CommonModule, ReactiveFormsModule, MnButton, MnFormBodyComponent, MnCustomBodyHostComponent, MnFooterActionsComponent], template: "<div class=\"flex flex-col gap-6\" [class.h-full]=\"config.sizeHeight\">\n @if (config.component || config.template) {\n <mn-custom-body-host\n [config]=\"asAny(config)\"\n [modalRef]=\"asAny(modalRef)\"\n class=\"block\"\n ></mn-custom-body-host>\n }\n\n <div class=\"
|
|
5519
|
+
args: [{ selector: 'mn-wizard-body', standalone: true, imports: [CommonModule, ReactiveFormsModule, MnButton, MnFormBodyComponent, MnCustomBodyHostComponent, MnFooterActionsComponent], template: "<div class=\"flex flex-col gap-6\" [class.h-full]=\"config.sizeHeight\">\n @if (config.component || config.template) {\n <mn-custom-body-host\n [config]=\"asAny(config)\"\n [modalRef]=\"asAny(modalRef)\"\n class=\"block\"\n ></mn-custom-body-host>\n }\n\n <div class=\"pb-4 border-b border-base-300 -mx-6 px-6 -mt-4\">\n <div class=\"relative flex items-start\">\n <!-- Background line spanning from first circle center to last circle center -->\n <div\n [style.left]=\"'calc(' + 100 / (2 * visibleSteps.length) + '%)'\"\n [style.right]=\"'calc(' + 100 / (2 * visibleSteps.length) + '%)'\"\n class=\"absolute top-[15px] h-1 bg-base-300 z-0\"\n ></div>\n\n <!-- Progress fill line -->\n @if (visibleSteps.length > 1) {\n <div\n [style.left]=\"'calc(' + 100 / (2 * visibleSteps.length) + '%)'\"\n [style.width]=\"'calc(' + (currentProgressIndex / (visibleSteps.length - 1)) * (100 - 100 / visibleSteps.length) + '%)'\"\n class=\"absolute top-[15px] h-1 bg-success z-[1] transition-all duration-500\"\n ></div>\n }\n\n @for (step of visibleSteps; track step.id; let i = $index; let last = $last) {\n <div\n (click)=\"isFreeFlow ? goToStep(step) : null\"\n [class.cursor-pointer]=\"isFreeFlow && canNavigateToStep(step)\"\n class=\"relative flex flex-col items-center gap-1 z-10 w-0 flex-1\"\n >\n <div\n [ngClass]=\"{\n 'bg-primary text-primary-content': step.id === currentStepId,\n 'bg-success text-success-content': visitedStepIds.includes(step.id) && step.id !== currentStepId,\n 'bg-base-200 text-base-content/50': !visitedStepIds.includes(step.id) && step.id !== currentStepId\n }\"\n class=\"w-8 h-8 rounded-full flex items-center justify-center font-semibold transition-all text-sm\"\n >{{ i + 1 }}\n </div>\n <div\n [ngClass]=\"{\n 'text-base-content font-semibold': step.id === currentStepId,\n 'text-base-content/50': step.id !== currentStepId\n }\"\n class=\"text-xs text-center whitespace-nowrap\"\n >{{ step.title }}\n </div>\n\n </div>\n }\n </div>\n </div>\n\n <div class=\"min-h-48 flex-1\">\n @for (step of config.steps; track step.id) {\n <div [style.display]=\"step.id === currentStepId ? 'block' : 'none'\">\n <h3 class=\"text-lg font-semibold text-base-content mb-4\">{{ step.title }}</h3>\n <div class=\"text-base-content/80\">\n <!-- Form step -->\n @if (stepFormConfigs[step.id]) {\n <mn-form-body\n [config]=\"stepFormConfigs[step.id]\"\n [modalRef]=\"asAny(modalRef)\"\n [hideFooter]=\"true\"\n [hideCustomBody]=\"true\"\n ></mn-form-body>\n }\n\n <!-- Text body -->\n @if (!stepFormConfigs[step.id] && isTextBody(step)) {\n <div>\n {{ step.body }}\n </div>\n }\n\n <!-- Dynamic content container for component/template bodies -->\n <ng-container #dynamicContainer></ng-container>\n </div>\n </div>\n }\n </div>\n\n <!-- Wizard-level errors (from onBeforeComplete) -->\n @if (wizardErrors && (wizardErrors | keyvalue).length > 0) {\n <div class=\"flex flex-col gap-1 px-2 py-2 bg-red-50 rounded-md\">\n @for (err of wizardErrors | keyvalue; track err.key) {\n <div class=\"text-red-500 text-sm\">\n {{ err.value }}\n </div>\n }\n </div>\n }\n\n <div class=\"flex gap-3 pt-4 border-t border-base-300\">\n @if (!currentStep?.hideBack) {\n <button\n mnButton\n [data]=\"{ variant: 'outline', color: 'secondary' }\"\n (click)=\"back()\"\n >\n {{ currentStep?.backLabel || (canGoBack ? labels.back : labels.close) }}\n </button>\n }\n\n <!-- Custom footer actions -->\n @if (config.footerActions) {\n <mn-footer-actions\n [actions]=\"config.footerActions\"\n (actionClick)=\"handleFooterAction($event)\"\n ></mn-footer-actions>\n } @else {\n <div class=\"flex-1\"></div>\n }\n\n @if (!isLastStep) {\n <button\n mnButton\n [data]=\"{ variant: 'fill', color: 'primary', disabled: !isCurrentStepValid }\"\n (click)=\"next()\"\n >\n {{ currentStep?.nextLabel || labels.next }}\n </button>\n }\n\n @if (isLastStep) {\n <button\n mnButton\n [data]=\"{ variant: 'fill', color: 'primary', disabled: !isCurrentStepValid || isCompleting }\"\n [disabled]=\"!isCurrentStepValid || isCompleting\"\n (click)=\"complete()\"\n >\n {{ currentStep?.nextLabel || (isCompleting ? labels.completing : labels.complete) }}\n </button>\n }\n </div>\n</div>\n" }]
|
|
5447
5520
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { config: [{
|
|
5448
5521
|
type: Input
|
|
5449
5522
|
}], modalRef: [{
|
|
@@ -5820,7 +5893,7 @@ class MnModalShellComponent {
|
|
|
5820
5893
|
}
|
|
5821
5894
|
}
|
|
5822
5895
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnModalShellComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
5823
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnModalShellComponent, isStandalone: true, selector: "mn-modal-shell", inputs: { config: "config", modalRef: "modalRef" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" }, properties: { "class": "this.hostClasses" } }, ngImport: i0, template: "@if (showBackdrop) {\n <div class=\"modal-backdrop absolute inset-0 bg-black/50 animate-[fadeIn_0.2s_ease-in-out]\" (click)=\"onBackdropClick()\"></div>\n}\n\n<div\n class=\"modal-container relative bg-base-100 rounded-lg shadow-xl max-h-[90vh] overflow-hidden flex flex-col\"\n [ngClass]=\"[containerSizeClass, animationClass]\"\n [style.min-height]=\"containerHeightStyle\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"config.title ? 'mn-modal-title' : null\"\n [attr.aria-describedby]=\"config.description ? 'mn-modal-description' : null\"\n tabindex=\"-1\"\n (click)=\"$event.stopPropagation()\"\n>\n <div class=\"flex items-center justify-between p-6
|
|
5896
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnModalShellComponent, isStandalone: true, selector: "mn-modal-shell", inputs: { config: "config", modalRef: "modalRef" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" }, properties: { "class": "this.hostClasses" } }, ngImport: i0, template: "@if (showBackdrop) {\n <div class=\"modal-backdrop absolute inset-0 bg-black/50 animate-[fadeIn_0.2s_ease-in-out]\" (click)=\"onBackdropClick()\"></div>\n}\n\n<div\n class=\"modal-container relative bg-base-100 rounded-lg shadow-xl max-h-[90vh] overflow-hidden flex flex-col\"\n [ngClass]=\"[containerSizeClass, animationClass]\"\n [style.min-height]=\"containerHeightStyle\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"config.title ? 'mn-modal-title' : null\"\n [attr.aria-describedby]=\"config.description ? 'mn-modal-description' : null\"\n tabindex=\"-1\"\n (click)=\"$event.stopPropagation()\"\n>\n <div [class.border-b]=\"config.kind !== ModalKind.WIZARD\"\n [class.border-base-300]=\"config.kind !== ModalKind.WIZARD\"\n class=\"flex items-center justify-between p-6\">\n <div class=\"flex flex-col gap-0.5\">\n @if (config.title) {\n <h2 class=\"m-0 text-xl font-semibold text-base-content\" id=\"mn-modal-title\">{{ config.title }}</h2>\n }\n @if (config.subtitle) {\n <p class=\"m-0 text-sm text-base-content/60 font-normal\">{{ config.subtitle }}</p>\n }\n </div>\n @if (showCloseButton) {\n <button\n class=\"bg-transparent border-none text-2xl cursor-pointer text-base-content/50 p-0 w-8 h-8 flex items-center justify-center rounded transition-colors hover:bg-base-200 hover:text-base-content\"\n (click)=\"onCloseButtonClick()\"\n aria-label=\"Close modal\"\n >\n \u00D7\n </button>\n }\n </div>\n @if (config.description) {\n <p class=\"m-0 px-6 text-sm text-base-content/60 leading-relaxed\" id=\"mn-modal-description\">{{ config.description }}</p>\n }\n\n <div class=\"flex-1 overflow-y-auto p-6\">\n @if (config.kind === ModalKind.WIZARD) {\n <mn-wizard-body\n [config]=\"asWizard(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-wizard-body>\n }\n\n @if (config.kind === ModalKind.FORM) {\n <mn-form-body\n [config]=\"asForm(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-form-body>\n }\n\n @if (config.kind === ModalKind.CONFIRMATION) {\n <mn-confirmation-body\n [config]=\"asConfirmation(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-confirmation-body>\n }\n\n @if (config.kind === ModalKind.CUSTOM) {\n <mn-custom-body-host\n [config]=\"asCustom(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-custom-body-host>\n }\n </div>\n\n <!-- Custom Footer Actions (not for wizard modals, they render their own) -->\n @if (hasCustomFooterActions && config.kind !== ModalKind.WIZARD) {\n <div class=\"flex gap-3 p-6 border-t border-base-300\">\n <mn-footer-actions\n [actions]=\"config.footerActions || []\"\n (actionClick)=\"onFooterAction($event)\"\n ></mn-footer-actions>\n </div>\n }\n</div>\n", styles: [":host{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;transition:transform .3s ease-in-out,filter .3s ease-in-out,opacity .3s ease-in-out}:host(.is-stacked){transform:scale(.96) translateY(-1rem);filter:brightness(.9) blur(1px);pointer-events:none;opacity:.8}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes zoomIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes slideOut{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes zoomOut{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}:host(.closing) .modal-backdrop{animation:fadeOut .15s ease-in-out forwards}:host(.closing).anim-slide .modal-container{animation:slideOut .15s ease-in-out forwards}:host(.closing).anim-fade .modal-container{animation:fadeOut .15s ease-in-out forwards}:host(.closing).anim-zoom .modal-container{animation:zoomOut .15s ease-in-out forwards}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MnWizardBodyComponent, selector: "mn-wizard-body", inputs: ["config", "modalRef"] }, { kind: "component", type: MnFormBodyComponent, selector: "mn-form-body", inputs: ["config", "modalRef", "hideFooter", "hideCustomBody"], outputs: ["formStatusChange"] }, { kind: "component", type: MnConfirmationBodyComponent, selector: "mn-confirmation-body", inputs: ["config", "modalRef"] }, { kind: "component", type: MnCustomBodyHostComponent, selector: "mn-custom-body-host", inputs: ["config", "modalRef"] }, { kind: "component", type: MnFooterActionsComponent, selector: "mn-footer-actions", inputs: ["actions"], outputs: ["actionClick"] }] });
|
|
5824
5897
|
}
|
|
5825
5898
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnModalShellComponent, decorators: [{
|
|
5826
5899
|
type: Component,
|
|
@@ -5831,7 +5904,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
5831
5904
|
MnConfirmationBodyComponent,
|
|
5832
5905
|
MnCustomBodyHostComponent,
|
|
5833
5906
|
MnFooterActionsComponent,
|
|
5834
|
-
], template: "@if (showBackdrop) {\n <div class=\"modal-backdrop absolute inset-0 bg-black/50 animate-[fadeIn_0.2s_ease-in-out]\" (click)=\"onBackdropClick()\"></div>\n}\n\n<div\n class=\"modal-container relative bg-base-100 rounded-lg shadow-xl max-h-[90vh] overflow-hidden flex flex-col\"\n [ngClass]=\"[containerSizeClass, animationClass]\"\n [style.min-height]=\"containerHeightStyle\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"config.title ? 'mn-modal-title' : null\"\n [attr.aria-describedby]=\"config.description ? 'mn-modal-description' : null\"\n tabindex=\"-1\"\n (click)=\"$event.stopPropagation()\"\n>\n <div class=\"flex items-center justify-between p-6
|
|
5907
|
+
], template: "@if (showBackdrop) {\n <div class=\"modal-backdrop absolute inset-0 bg-black/50 animate-[fadeIn_0.2s_ease-in-out]\" (click)=\"onBackdropClick()\"></div>\n}\n\n<div\n class=\"modal-container relative bg-base-100 rounded-lg shadow-xl max-h-[90vh] overflow-hidden flex flex-col\"\n [ngClass]=\"[containerSizeClass, animationClass]\"\n [style.min-height]=\"containerHeightStyle\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"config.title ? 'mn-modal-title' : null\"\n [attr.aria-describedby]=\"config.description ? 'mn-modal-description' : null\"\n tabindex=\"-1\"\n (click)=\"$event.stopPropagation()\"\n>\n <div [class.border-b]=\"config.kind !== ModalKind.WIZARD\"\n [class.border-base-300]=\"config.kind !== ModalKind.WIZARD\"\n class=\"flex items-center justify-between p-6\">\n <div class=\"flex flex-col gap-0.5\">\n @if (config.title) {\n <h2 class=\"m-0 text-xl font-semibold text-base-content\" id=\"mn-modal-title\">{{ config.title }}</h2>\n }\n @if (config.subtitle) {\n <p class=\"m-0 text-sm text-base-content/60 font-normal\">{{ config.subtitle }}</p>\n }\n </div>\n @if (showCloseButton) {\n <button\n class=\"bg-transparent border-none text-2xl cursor-pointer text-base-content/50 p-0 w-8 h-8 flex items-center justify-center rounded transition-colors hover:bg-base-200 hover:text-base-content\"\n (click)=\"onCloseButtonClick()\"\n aria-label=\"Close modal\"\n >\n \u00D7\n </button>\n }\n </div>\n @if (config.description) {\n <p class=\"m-0 px-6 text-sm text-base-content/60 leading-relaxed\" id=\"mn-modal-description\">{{ config.description }}</p>\n }\n\n <div class=\"flex-1 overflow-y-auto p-6\">\n @if (config.kind === ModalKind.WIZARD) {\n <mn-wizard-body\n [config]=\"asWizard(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-wizard-body>\n }\n\n @if (config.kind === ModalKind.FORM) {\n <mn-form-body\n [config]=\"asForm(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-form-body>\n }\n\n @if (config.kind === ModalKind.CONFIRMATION) {\n <mn-confirmation-body\n [config]=\"asConfirmation(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-confirmation-body>\n }\n\n @if (config.kind === ModalKind.CUSTOM) {\n <mn-custom-body-host\n [config]=\"asCustom(config)\"\n [modalRef]=\"asAny(modalRef)\"\n ></mn-custom-body-host>\n }\n </div>\n\n <!-- Custom Footer Actions (not for wizard modals, they render their own) -->\n @if (hasCustomFooterActions && config.kind !== ModalKind.WIZARD) {\n <div class=\"flex gap-3 p-6 border-t border-base-300\">\n <mn-footer-actions\n [actions]=\"config.footerActions || []\"\n (actionClick)=\"onFooterAction($event)\"\n ></mn-footer-actions>\n </div>\n }\n</div>\n", styles: [":host{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;transition:transform .3s ease-in-out,filter .3s ease-in-out,opacity .3s ease-in-out}:host(.is-stacked){transform:scale(.96) translateY(-1rem);filter:brightness(.9) blur(1px);pointer-events:none;opacity:.8}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-1rem)}to{opacity:1;transform:translateY(0)}}@keyframes zoomIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes slideOut{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(1rem)}}@keyframes zoomOut{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}:host(.closing) .modal-backdrop{animation:fadeOut .15s ease-in-out forwards}:host(.closing).anim-slide .modal-container{animation:slideOut .15s ease-in-out forwards}:host(.closing).anim-fade .modal-container{animation:fadeOut .15s ease-in-out forwards}:host(.closing).anim-zoom .modal-container{animation:zoomOut .15s ease-in-out forwards}\n"] }]
|
|
5835
5908
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{
|
|
5836
5909
|
type: Input
|
|
5837
5910
|
}], modalRef: [{
|