@meshmakers/octo-ui 3.4.150 → 3.4.160

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.
@@ -271,10 +271,10 @@ class SettingsPageComponent {
271
271
  return m.logoFavicon;
272
272
  }
273
273
  }
274
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SettingsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
275
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: SettingsPageComponent, isStandalone: true, selector: "mm-branding-settings", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"settings-page\">\n <form [formGroup]=\"settingsForm\" (ngSubmit)=\"onSubmit()\">\n\n <!-- General -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionGeneral }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"form-row\">\n <kendo-formfield [title]=\"messages().appName\">\n <kendo-label [text]=\"messages().appName\" [optional]=\"false\" />\n <input kendoTextBox formControlName=\"appName\" [required]=\"true\" />\n <kendo-formerror>\n {{ messages().appName }} {{ messages().required }}\n </kendo-formerror>\n </kendo-formfield>\n <kendo-formfield [title]=\"messages().appTitle\">\n <kendo-label [text]=\"messages().appTitle\" [optional]=\"true\" />\n <input kendoTextBox formControlName=\"appTitle\" />\n </kendo-formfield>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Logos -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLogos }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"logo-upload-row\">\n @for (slot of logoSlotNames; track slot) {\n <div class=\"file-upload-section\">\n <label class=\"upload-label\" [attr.for]=\"'logo-' + slot\">\n {{ logoLabel(slot) }}\n </label>\n <div\n class=\"logo-dropzone\"\n [class.logo-dropzone--active]=\"isDragOver(slot)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"logoLabel(slot)\"\n (click)=\"logoInput.click()\"\n (keydown.enter)=\"logoInput.click()\"\n (keydown.space)=\"$event.preventDefault(); logoInput.click()\"\n (dragover)=\"onLogoDragOver(slot, $event)\"\n (dragleave)=\"onLogoDragLeave(slot)\"\n (drop)=\"onLogoDropped(slot, $event)\"\n >\n <span class=\"logo-dropzone__label\">\n {{ slot === 'favicon' ? messages().uploadFavicon : messages().uploadLogo }}\n </span>\n <input\n #logoInput\n type=\"file\"\n accept=\"image/*\"\n [id]=\"'logo-' + slot\"\n (change)=\"onLogoSelected(slot, $event)\"\n class=\"logo-dropzone__input\"\n />\n </div>\n @let url = previewUrl(slot);\n @if (url) {\n <div class=\"logo-preview\">\n <img [src]=\"url\" [alt]=\"logoLabel(slot) + ' preview'\" />\n <button\n kendoButton\n type=\"button\"\n fillMode=\"flat\"\n [svgIcon]=\"xIcon\"\n (click)=\"clearLogo(slot)\"\n [attr.aria-label]=\"messages().logoRemove\"\n ></button>\n </div>\n }\n </div>\n }\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Light Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLightTheme }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightHeaderGradientStart')?.value + ', ' + settingsForm.get('lightHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightFooterGradientStart')?.value + ', ' + settingsForm.get('lightFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Dark Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header class=\"dark-theme-header\">\n <h3 class=\"card-title\">{{ messages().sectionDarkTheme }}</h3>\n <label class=\"dark-theme-toggle\">\n <kendo-switch formControlName=\"darkThemeEnabled\"></kendo-switch>\n <span>{{ messages().enableDarkTheme }}</span>\n </label>\n </kendo-card-header>\n @if (darkThemeEnabled()) {\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkHeaderGradientStart')?.value + ', ' + settingsForm.get('darkHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkFooterGradientStart')?.value + ', ' + settingsForm.get('darkFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n }\n </kendo-card>\n\n <div class=\"form-actions-bar\">\n <button\n kendoButton\n type=\"button\"\n themeColor=\"base\"\n [svgIcon]=\"undoIcon\"\n [disabled]=\"saving()\"\n (click)=\"onResetDefaults()\"\n >\n {{ messages().resetDefaults }}\n </button>\n <button\n kendoButton\n type=\"submit\"\n themeColor=\"primary\"\n [svgIcon]=\"saveIcon\"\n [disabled]=\"!settingsForm.valid || saving()\"\n >\n {{ messages().save }}\n </button>\n </div>\n </form>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.settings-page{width:100%;padding:16px;box-sizing:border-box}kendo-card.settings-card{margin-bottom:16px;width:100%!important}.card-title{margin:0;font-size:1.1rem;font-weight:500}.form-row{display:flex;gap:16px;flex-wrap:wrap}.form-row kendo-formfield{flex:1 1 240px}.form-actions-bar{position:sticky;bottom:12px;display:flex;justify-content:flex-end;gap:8px;margin-top:16px;padding:12px 16px;background:var(--kendo-color-surface, #fff);border:1px solid var(--color-surface-200, color-mix(in oklch, var(--kendo-color-app-surface), currentColor 18%));border-radius:12px;box-shadow:0 6px 18px -8px #0f172a2e;z-index:1}.logo-upload-row{display:flex;gap:16px;flex-wrap:wrap}.file-upload-section{flex:1 1 220px}.upload-label{display:block;margin-bottom:4px;font-size:12px;color:var(--kendo-color-subtle, rgba(0, 0, 0, .6))}.logo-dropzone{margin-top:4px;height:80px;display:flex;align-items:center;justify-content:center;border:2px dashed var(--kendo-color-border, #d5d5d5);border-radius:4px;background:var(--kendo-color-surface-alt, transparent);cursor:pointer;transition:border-color .12s ease,background .12s ease}.logo-dropzone:hover,.logo-dropzone:focus-visible{border-color:var(--kendo-color-primary, #5ac4be);outline:none}.logo-dropzone--active{border-color:var(--kendo-color-primary, #5ac4be);background:color-mix(in srgb,var(--kendo-color-primary, #5ac4be) 8%,transparent)}.logo-dropzone__label{font-size:.9rem;color:var(--kendo-color-subtle, rgba(0, 0, 0, .55));pointer-events:none}.logo-dropzone__input{display:none}.logo-preview{display:flex;align-items:center;gap:10px;margin-top:8px;position:relative}.logo-preview img{max-width:200px;max-height:80px;object-fit:contain;border:1px solid var(--kendo-color-border, #ddd);border-radius:4px;padding:4px}.logo-preview button{position:absolute;top:-8px;right:-8px}.color-grid{display:flex;gap:32px;flex-wrap:wrap}.color-field{display:flex;flex-direction:column;gap:4px}.color-label{font-size:12px;color:var(--kendo-color-subtle, rgba(0, 0, 0, .6))}.subsection-title{margin:16px 0 8px;font-size:.95rem;font-weight:500;color:var(--kendo-color-subtle, #666)}.gradient-section{border-top:1px solid var(--kendo-color-border, #e0e0e0);margin-top:16px;padding-top:4px}.gradient-row{display:flex;align-items:stretch;gap:16px}.gradient-row .color-field{flex:0 0 auto}.gradient-row .color-field.gradient-preview-col{flex:1 1 auto;min-width:0}.gradient-preview-col .color-label{visibility:hidden}.gradient-preview{flex:1;width:100%;border-radius:4px;border:1px solid var(--kendo-color-border, #e0e0e0)}.dark-theme-header{display:flex;align-items:center;justify-content:space-between;gap:16px}.dark-theme-toggle{display:inline-flex;align-items:center;gap:8px;font-size:.95rem;cursor:pointer;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: InputsModule }, { kind: "directive", type: i1.TextBoxDirective, selector: "input[kendoTextBox]", inputs: ["value"] }, { kind: "component", type: i1.SwitchComponent, selector: "kendo-switch", inputs: ["focusableId", "onLabel", "offLabel", "checked", "disabled", "readonly", "tabindex", "size", "thumbRounded", "trackRounded", "tabIndex"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoSwitch"] }, { kind: "component", type: i1.FormFieldComponent, selector: "kendo-formfield", inputs: ["showHints", "orientation", "showErrors", "colSpan"] }, { kind: "component", type: i1.ErrorComponent, selector: "kendo-formerror", inputs: ["align"] }, { kind: "component", type: i1.ColorPickerComponent, selector: "kendo-colorpicker", inputs: ["views", "view", "adaptiveMode", "activeView", "readonly", "disabled", "format", "value", "popupSettings", "paletteSettings", "gradientSettings", "icon", "iconClass", "svgIcon", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "tabindex", "preview", "actionsLayout", "size", "rounded", "fillMode"], outputs: ["valueChange", "open", "close", "focus", "blur", "cancel", "activeColorClick", "clearButtonClick", "activeViewChange"], exportAs: ["kendoColorPicker"] }, { kind: "ngmodule", type: LabelModule }, { kind: "component", type: i2.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: LayoutModule }, { kind: "component", type: i4.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i4.CardBodyComponent, selector: "kendo-card-body" }, { kind: "component", type: i4.CardHeaderComponent, selector: "kendo-card-header" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
274
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SettingsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
275
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SettingsPageComponent, isStandalone: true, selector: "mm-branding-settings", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"settings-page\">\n <form [formGroup]=\"settingsForm\" (ngSubmit)=\"onSubmit()\">\n\n <!-- General -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionGeneral }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"form-row\">\n <kendo-formfield [title]=\"messages().appName\">\n <kendo-label [text]=\"messages().appName\" [optional]=\"false\" />\n <input kendoTextBox formControlName=\"appName\" [required]=\"true\" />\n <kendo-formerror>\n {{ messages().appName }} {{ messages().required }}\n </kendo-formerror>\n </kendo-formfield>\n <kendo-formfield [title]=\"messages().appTitle\">\n <kendo-label [text]=\"messages().appTitle\" [optional]=\"true\" />\n <input kendoTextBox formControlName=\"appTitle\" />\n </kendo-formfield>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Logos -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLogos }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"logo-upload-row\">\n @for (slot of logoSlotNames; track slot) {\n <div class=\"file-upload-section\">\n <label class=\"upload-label\" [attr.for]=\"'logo-' + slot\">\n {{ logoLabel(slot) }}\n </label>\n <div\n class=\"logo-dropzone\"\n [class.logo-dropzone--active]=\"isDragOver(slot)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"logoLabel(slot)\"\n (click)=\"logoInput.click()\"\n (keydown.enter)=\"logoInput.click()\"\n (keydown.space)=\"$event.preventDefault(); logoInput.click()\"\n (dragover)=\"onLogoDragOver(slot, $event)\"\n (dragleave)=\"onLogoDragLeave(slot)\"\n (drop)=\"onLogoDropped(slot, $event)\"\n >\n <span class=\"logo-dropzone__label\">\n {{ slot === 'favicon' ? messages().uploadFavicon : messages().uploadLogo }}\n </span>\n <input\n #logoInput\n type=\"file\"\n accept=\"image/*\"\n [id]=\"'logo-' + slot\"\n (change)=\"onLogoSelected(slot, $event)\"\n class=\"logo-dropzone__input\"\n />\n </div>\n @let url = previewUrl(slot);\n @if (url) {\n <div class=\"logo-preview\">\n <img [src]=\"url\" [alt]=\"logoLabel(slot) + ' preview'\" />\n <button\n kendoButton\n type=\"button\"\n fillMode=\"flat\"\n [svgIcon]=\"xIcon\"\n (click)=\"clearLogo(slot)\"\n [attr.aria-label]=\"messages().logoRemove\"\n ></button>\n </div>\n }\n </div>\n }\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Light Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLightTheme }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightHeaderGradientStart')?.value + ', ' + settingsForm.get('lightHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightFooterGradientStart')?.value + ', ' + settingsForm.get('lightFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Dark Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header class=\"dark-theme-header\">\n <h3 class=\"card-title\">{{ messages().sectionDarkTheme }}</h3>\n <label class=\"dark-theme-toggle\">\n <kendo-switch formControlName=\"darkThemeEnabled\"></kendo-switch>\n <span>{{ messages().enableDarkTheme }}</span>\n </label>\n </kendo-card-header>\n @if (darkThemeEnabled()) {\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkHeaderGradientStart')?.value + ', ' + settingsForm.get('darkHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkFooterGradientStart')?.value + ', ' + settingsForm.get('darkFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n }\n </kendo-card>\n\n <div class=\"form-actions-bar\">\n <button\n kendoButton\n type=\"button\"\n themeColor=\"base\"\n [svgIcon]=\"undoIcon\"\n [disabled]=\"saving()\"\n (click)=\"onResetDefaults()\"\n >\n {{ messages().resetDefaults }}\n </button>\n <button\n kendoButton\n type=\"submit\"\n themeColor=\"primary\"\n [svgIcon]=\"saveIcon\"\n [disabled]=\"!settingsForm.valid || saving()\"\n >\n {{ messages().save }}\n </button>\n </div>\n </form>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.settings-page{width:100%;padding:16px;box-sizing:border-box}kendo-card.settings-card{margin-bottom:16px;width:100%!important}.card-title{margin:0;font-size:1.1rem;font-weight:500}.form-row{display:flex;gap:16px;flex-wrap:wrap}.form-row kendo-formfield{flex:1 1 240px}.form-actions-bar{position:sticky;bottom:12px;display:flex;justify-content:flex-end;gap:8px;margin-top:16px;padding:12px 16px;background:var(--kendo-color-surface, #fff);border:1px solid var(--color-surface-200, color-mix(in oklch, var(--kendo-color-app-surface), currentColor 18%));border-radius:12px;box-shadow:0 6px 18px -8px #0f172a2e;z-index:1}.logo-upload-row{display:flex;gap:16px;flex-wrap:wrap}.file-upload-section{flex:1 1 220px}.upload-label{display:block;margin-bottom:4px;font-size:12px;color:var(--kendo-color-subtle, rgba(0, 0, 0, .6))}.logo-dropzone{margin-top:4px;height:80px;display:flex;align-items:center;justify-content:center;border:2px dashed var(--kendo-color-border, #d5d5d5);border-radius:4px;background:var(--kendo-color-surface-alt, transparent);cursor:pointer;transition:border-color .12s ease,background .12s ease}.logo-dropzone:hover,.logo-dropzone:focus-visible{border-color:var(--kendo-color-primary, #5ac4be);outline:none}.logo-dropzone--active{border-color:var(--kendo-color-primary, #5ac4be);background:color-mix(in srgb,var(--kendo-color-primary, #5ac4be) 8%,transparent)}.logo-dropzone__label{font-size:.9rem;color:var(--kendo-color-subtle, rgba(0, 0, 0, .55));pointer-events:none}.logo-dropzone__input{display:none}.logo-preview{display:flex;align-items:center;gap:10px;margin-top:8px;position:relative}.logo-preview img{max-width:200px;max-height:80px;object-fit:contain;border:1px solid var(--kendo-color-border, #ddd);border-radius:4px;padding:4px}.logo-preview button{position:absolute;top:-8px;right:-8px}.color-grid{display:flex;gap:32px;flex-wrap:wrap}.color-field{display:flex;flex-direction:column;gap:4px}.color-label{font-size:12px;color:var(--kendo-color-subtle, rgba(0, 0, 0, .6))}.subsection-title{margin:16px 0 8px;font-size:.95rem;font-weight:500;color:var(--kendo-color-subtle, #666)}.gradient-section{border-top:1px solid var(--kendo-color-border, #e0e0e0);margin-top:16px;padding-top:4px}.gradient-row{display:flex;align-items:stretch;gap:16px}.gradient-row .color-field{flex:0 0 auto}.gradient-row .color-field.gradient-preview-col{flex:1 1 auto;min-width:0}.gradient-preview-col .color-label{visibility:hidden}.gradient-preview{flex:1;width:100%;border-radius:4px;border:1px solid var(--kendo-color-border, #e0e0e0)}.dark-theme-header{display:flex;align-items:center;justify-content:space-between;gap:16px}.dark-theme-toggle{display:inline-flex;align-items:center;gap:8px;font-size:.95rem;cursor:pointer;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: InputsModule }, { kind: "directive", type: i1.TextBoxDirective, selector: "input[kendoTextBox]", inputs: ["value"] }, { kind: "component", type: i1.SwitchComponent, selector: "kendo-switch", inputs: ["focusableId", "onLabel", "offLabel", "checked", "disabled", "readonly", "tabindex", "size", "thumbRounded", "trackRounded", "tabIndex"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoSwitch"] }, { kind: "component", type: i1.FormFieldComponent, selector: "kendo-formfield", inputs: ["showHints", "orientation", "showErrors", "colSpan"] }, { kind: "component", type: i1.ErrorComponent, selector: "kendo-formerror", inputs: ["align"] }, { kind: "component", type: i1.ColorPickerComponent, selector: "kendo-colorpicker", inputs: ["views", "view", "adaptiveMode", "activeView", "readonly", "disabled", "format", "value", "popupSettings", "paletteSettings", "gradientSettings", "icon", "iconClass", "svgIcon", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "tabindex", "preview", "actionsLayout", "size", "rounded", "fillMode"], outputs: ["valueChange", "open", "close", "focus", "blur", "cancel", "activeColorClick", "clearButtonClick", "activeViewChange"], exportAs: ["kendoColorPicker"] }, { kind: "ngmodule", type: LabelModule }, { kind: "component", type: i2.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: LayoutModule }, { kind: "component", type: i4.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i4.CardBodyComponent, selector: "kendo-card-body" }, { kind: "component", type: i4.CardHeaderComponent, selector: "kendo-card-header" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
276
276
  }
277
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: SettingsPageComponent, decorators: [{
277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SettingsPageComponent, decorators: [{
278
278
  type: Component,
279
279
  args: [{ selector: 'mm-branding-settings', standalone: true, imports: [
280
280
  InputsModule,
@@ -1 +1 @@
1
- {"version":3,"file":"meshmakers-octo-ui-branding-settings.mjs","sources":["../../../../projects/meshmakers/octo-ui/branding-settings/src/settings-page.component.ts","../../../../projects/meshmakers/octo-ui/branding-settings/src/settings-page.component.html","../../../../projects/meshmakers/octo-ui/branding-settings/src/branding-settings.routes.ts","../../../../projects/meshmakers/octo-ui/branding-settings/src/public-api.ts","../../../../projects/meshmakers/octo-ui/branding-settings/src/meshmakers-octo-ui-branding-settings.ts"],"sourcesContent":["import { Component, inject, input, OnInit, signal } from '@angular/core';\nimport {\n FormBuilder,\n FormControl,\n FormGroup,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport {\n BrandingData,\n BrandingDataSource,\n OCTO_BRANDING_DEFAULTS,\n ThemePalette,\n} from '@meshmakers/octo-ui/branding';\nimport { MessageService } from '@meshmakers/shared-services';\nimport { ButtonsModule } from '@progress/kendo-angular-buttons';\nimport { InputsModule } from '@progress/kendo-angular-inputs';\nimport { LabelModule } from '@progress/kendo-angular-label';\nimport { LayoutModule } from '@progress/kendo-angular-layout';\nimport { saveIcon, undoIcon, xIcon } from '@progress/kendo-svg-icons';\nimport { BrandingSettingsMessages } from './branding-settings.messages';\n\ntype LogoSlotName = 'header' | 'footer' | 'favicon';\n\ninterface LogoSlot {\n file: File | null;\n preview: string | null;\n cleared: boolean;\n}\n\nconst EMPTY_LOGO_SLOT: LogoSlot = {\n file: null,\n preview: null,\n cleared: false,\n};\n\n@Component({\n selector: 'mm-branding-settings',\n standalone: true,\n imports: [\n InputsModule,\n LabelModule,\n ButtonsModule,\n LayoutModule,\n ReactiveFormsModule,\n ],\n templateUrl: './settings-page.component.html',\n styleUrl: './settings-page.component.scss',\n})\nexport class SettingsPageComponent implements OnInit {\n readonly messages = input.required<BrandingSettingsMessages>();\n\n private readonly fb = inject(FormBuilder);\n private readonly branding = inject(BrandingDataSource);\n private readonly messageService = inject(MessageService);\n private readonly defaults = inject(OCTO_BRANDING_DEFAULTS);\n\n protected readonly saveIcon = saveIcon;\n protected readonly undoIcon = undoIcon;\n protected readonly xIcon = xIcon;\n\n protected readonly logoSlotNames: readonly LogoSlotName[] = [\n 'header',\n 'footer',\n 'favicon',\n ];\n\n protected readonly saving = signal(false);\n\n protected readonly settingsForm: FormGroup;\n\n private readonly slotStates = {\n header: signal<LogoSlot>({ ...EMPTY_LOGO_SLOT }),\n footer: signal<LogoSlot>({ ...EMPTY_LOGO_SLOT }),\n favicon: signal<LogoSlot>({ ...EMPTY_LOGO_SLOT }),\n } as const satisfies Record<LogoSlotName, unknown>;\n\n private readonly persistedUrls = {\n header: signal<string | null>(null),\n footer: signal<string | null>(null),\n favicon: signal<string | null>(null),\n } as const satisfies Record<LogoSlotName, unknown>;\n\n constructor() {\n const { lightTheme, darkTheme } = this.defaults;\n const dark = darkTheme ?? lightTheme;\n\n // Seeding color controls with valid hex defaults is required: kendo-colorpicker\n // binds as a ControlValueAccessor and doesn't handle initial empty strings\n // cleanly inside kendo-formfield.\n this.settingsForm = this.fb.group({\n appName: [this.defaults.appName, Validators.required],\n appTitle: [this.defaults.appTitle],\n\n lightPrimaryColor: [lightTheme.primaryColor, Validators.required],\n lightSecondaryColor: [lightTheme.secondaryColor, Validators.required],\n lightTertiaryColor: [lightTheme.tertiaryColor, Validators.required],\n lightNeutralColor: [lightTheme.neutralColor, Validators.required],\n lightBackgroundColor: [lightTheme.backgroundColor],\n lightHeaderGradientStart: [lightTheme.headerGradient.startColor],\n lightHeaderGradientEnd: [lightTheme.headerGradient.endColor],\n lightFooterGradientStart: [lightTheme.footerGradient.startColor],\n lightFooterGradientEnd: [lightTheme.footerGradient.endColor],\n\n darkThemeEnabled: [darkTheme !== null],\n\n darkPrimaryColor: [dark.primaryColor, Validators.required],\n darkSecondaryColor: [dark.secondaryColor, Validators.required],\n darkTertiaryColor: [dark.tertiaryColor, Validators.required],\n darkNeutralColor: [dark.neutralColor, Validators.required],\n darkBackgroundColor: [dark.backgroundColor],\n darkHeaderGradientStart: [dark.headerGradient.startColor],\n darkHeaderGradientEnd: [dark.headerGradient.endColor],\n darkFooterGradientStart: [dark.footerGradient.startColor],\n darkFooterGradientEnd: [dark.footerGradient.endColor],\n });\n }\n\n protected darkThemeEnabled(): boolean {\n return this.settingsForm.get('darkThemeEnabled')?.value === true;\n }\n\n async ngOnInit(): Promise<void> {\n try {\n await this.branding.load();\n } catch (error) {\n console.error('[SettingsPageComponent] Failed to load branding', error);\n this.messageService.showError(this.messages().loadError);\n return;\n }\n this.hydrate(this.branding.branding());\n }\n\n private readonly dragOverSlot = signal<LogoSlotName | null>(null);\n\n protected isDragOver(slot: LogoSlotName): boolean {\n return this.dragOverSlot() === slot;\n }\n\n protected onLogoSelected(slot: LogoSlotName, event: Event): void {\n const input = event.target;\n if (!(input instanceof HTMLInputElement)) return;\n const file = input.files?.[0] ?? null;\n this.applyLogoFile(slot, file);\n input.value = '';\n }\n\n protected onLogoDragOver(slot: LogoSlotName, event: DragEvent): void {\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n this.dragOverSlot.set(slot);\n }\n\n protected onLogoDragLeave(slot: LogoSlotName): void {\n if (this.dragOverSlot() === slot) this.dragOverSlot.set(null);\n }\n\n protected onLogoDropped(slot: LogoSlotName, event: DragEvent): void {\n event.preventDefault();\n this.dragOverSlot.set(null);\n const file = event.dataTransfer?.files?.[0];\n if (!file || !file.type.startsWith('image/')) return;\n this.applyLogoFile(slot, file);\n }\n\n private applyLogoFile(slot: LogoSlotName, file: File | null): void {\n if (!file) return;\n const reader = new FileReader();\n reader.onload = (): void => {\n const result = reader.result;\n this.slotStates[slot].set({\n file,\n preview: typeof result === 'string' ? result : null,\n cleared: false,\n });\n };\n reader.readAsDataURL(file);\n }\n\n protected clearLogo(slot: LogoSlotName): void {\n this.slotStates[slot].set({ file: null, preview: null, cleared: true });\n this.persistedUrls[slot].set(null);\n }\n\n protected previewUrl(slot: LogoSlotName): string | null {\n return this.slotStates[slot]().preview ?? this.persistedUrls[slot]();\n }\n\n protected async onSubmit(): Promise<void> {\n if (this.settingsForm.invalid) {\n this.settingsForm.markAllAsTouched();\n return;\n }\n this.saving.set(true);\n try {\n await this.branding.save({\n appName: this.strValue('appName'),\n appTitle: this.strValue('appTitle'),\n headerLogoFile: this.logoFileForSave('header'),\n footerLogoFile: this.logoFileForSave('footer'),\n faviconFile: this.logoFileForSave('favicon'),\n lightTheme: this.paletteFromForm('light'),\n darkTheme: this.darkThemeEnabled() ? this.paletteFromForm('dark') : null,\n });\n this.messageService.showInformation(this.messages().saveSuccess);\n this.hydrate(this.branding.branding());\n this.settingsForm.markAsPristine();\n } catch (error) {\n console.error('[SettingsPageComponent] Failed to save branding', error);\n this.messageService.showError(this.messages().saveError);\n } finally {\n this.saving.set(false);\n }\n }\n\n protected async onResetDefaults(): Promise<void> {\n this.saving.set(true);\n try {\n await this.branding.resetToDefaults();\n this.hydrate(this.branding.branding());\n this.settingsForm.markAsPristine();\n this.messageService.showInformation(this.messages().resetSuccess);\n } catch (error) {\n console.error('[SettingsPageComponent] Failed to reset branding', error);\n this.messageService.showError(this.messages().saveError);\n } finally {\n this.saving.set(false);\n }\n }\n\n private hydrate(data: BrandingData): void {\n this.persistedUrls.header.set(data.headerLogoUrl);\n this.persistedUrls.footer.set(data.footerLogoUrl);\n this.persistedUrls.favicon.set(data.faviconUrl);\n\n for (const slot of this.logoSlotNames) {\n this.slotStates[slot].set({ ...EMPTY_LOGO_SLOT });\n }\n\n const dark =\n data.darkTheme ?? this.defaults.darkTheme ?? this.defaults.lightTheme;\n\n this.settingsForm.patchValue({\n appName: data.appName,\n appTitle: data.appTitle,\n darkThemeEnabled: data.darkTheme !== null,\n\n lightPrimaryColor: data.lightTheme.primaryColor,\n lightSecondaryColor: data.lightTheme.secondaryColor,\n lightTertiaryColor: data.lightTheme.tertiaryColor,\n lightNeutralColor: data.lightTheme.neutralColor,\n lightBackgroundColor: data.lightTheme.backgroundColor,\n lightHeaderGradientStart: data.lightTheme.headerGradient.startColor,\n lightHeaderGradientEnd: data.lightTheme.headerGradient.endColor,\n lightFooterGradientStart: data.lightTheme.footerGradient.startColor,\n lightFooterGradientEnd: data.lightTheme.footerGradient.endColor,\n\n darkPrimaryColor: dark.primaryColor,\n darkSecondaryColor: dark.secondaryColor,\n darkTertiaryColor: dark.tertiaryColor,\n darkNeutralColor: dark.neutralColor,\n darkBackgroundColor: dark.backgroundColor,\n darkHeaderGradientStart: dark.headerGradient.startColor,\n darkHeaderGradientEnd: dark.headerGradient.endColor,\n darkFooterGradientStart: dark.footerGradient.startColor,\n darkFooterGradientEnd: dark.footerGradient.endColor,\n });\n }\n\n private logoFileForSave(slot: LogoSlotName): File | null | undefined {\n const state = this.slotStates[slot]();\n if (state.file) return state.file;\n if (state.cleared) return null;\n return undefined;\n }\n\n private strValue(name: string): string {\n const value = this.settingsForm.get(name)?.value;\n return typeof value === 'string' ? value : '';\n }\n\n private paletteFromForm(kind: 'light' | 'dark'): ThemePalette {\n return {\n primaryColor: this.strValue(`${kind}PrimaryColor`),\n secondaryColor: this.strValue(`${kind}SecondaryColor`),\n tertiaryColor: this.strValue(`${kind}TertiaryColor`),\n neutralColor: this.strValue(`${kind}NeutralColor`),\n backgroundColor: this.strValue(`${kind}BackgroundColor`),\n headerGradient: {\n startColor: this.strValue(`${kind}HeaderGradientStart`),\n endColor: this.strValue(`${kind}HeaderGradientEnd`),\n },\n footerGradient: {\n startColor: this.strValue(`${kind}FooterGradientStart`),\n endColor: this.strValue(`${kind}FooterGradientEnd`),\n },\n };\n }\n\n // Used with `[formControl]` (not `formControlName`) on kendo-colorpicker:\n // FormControl directive accepts the control instance directly and avoids\n // FormControlName's @Self() injection that historically tripped on the\n // colorpicker's forwardRef NG_VALUE_ACCESSOR. Goes through Reactive Forms\n // properly (tracks dirty/touched/validators), unlike the old [value] +\n // (valueChange) workaround.\n protected colorCtrl(controlName: string): FormControl<string> {\n return this.settingsForm.get(controlName) as FormControl<string>;\n }\n\n /**\n * Resolves a localized label for a given logo slot. The maco-app source used\n * dynamic translate-key concatenation (`'Settings_Logo_' + slot | translate`);\n * the library expresses the same idea by mapping slot names to fields on the\n * `BrandingSettingsMessages` interface.\n */\n protected logoLabel(slot: LogoSlotName): string {\n const m = this.messages();\n switch (slot) {\n case 'header':\n return m.logoHeader;\n case 'footer':\n return m.logoFooter;\n case 'favicon':\n return m.logoFavicon;\n }\n }\n}\n","<div class=\"settings-page\">\n <form [formGroup]=\"settingsForm\" (ngSubmit)=\"onSubmit()\">\n\n <!-- General -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionGeneral }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"form-row\">\n <kendo-formfield [title]=\"messages().appName\">\n <kendo-label [text]=\"messages().appName\" [optional]=\"false\" />\n <input kendoTextBox formControlName=\"appName\" [required]=\"true\" />\n <kendo-formerror>\n {{ messages().appName }} {{ messages().required }}\n </kendo-formerror>\n </kendo-formfield>\n <kendo-formfield [title]=\"messages().appTitle\">\n <kendo-label [text]=\"messages().appTitle\" [optional]=\"true\" />\n <input kendoTextBox formControlName=\"appTitle\" />\n </kendo-formfield>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Logos -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLogos }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"logo-upload-row\">\n @for (slot of logoSlotNames; track slot) {\n <div class=\"file-upload-section\">\n <label class=\"upload-label\" [attr.for]=\"'logo-' + slot\">\n {{ logoLabel(slot) }}\n </label>\n <div\n class=\"logo-dropzone\"\n [class.logo-dropzone--active]=\"isDragOver(slot)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"logoLabel(slot)\"\n (click)=\"logoInput.click()\"\n (keydown.enter)=\"logoInput.click()\"\n (keydown.space)=\"$event.preventDefault(); logoInput.click()\"\n (dragover)=\"onLogoDragOver(slot, $event)\"\n (dragleave)=\"onLogoDragLeave(slot)\"\n (drop)=\"onLogoDropped(slot, $event)\"\n >\n <span class=\"logo-dropzone__label\">\n {{ slot === 'favicon' ? messages().uploadFavicon : messages().uploadLogo }}\n </span>\n <input\n #logoInput\n type=\"file\"\n accept=\"image/*\"\n [id]=\"'logo-' + slot\"\n (change)=\"onLogoSelected(slot, $event)\"\n class=\"logo-dropzone__input\"\n />\n </div>\n @let url = previewUrl(slot);\n @if (url) {\n <div class=\"logo-preview\">\n <img [src]=\"url\" [alt]=\"logoLabel(slot) + ' preview'\" />\n <button\n kendoButton\n type=\"button\"\n fillMode=\"flat\"\n [svgIcon]=\"xIcon\"\n (click)=\"clearLogo(slot)\"\n [attr.aria-label]=\"messages().logoRemove\"\n ></button>\n </div>\n }\n </div>\n }\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Light Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLightTheme }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightHeaderGradientStart')?.value + ', ' + settingsForm.get('lightHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightFooterGradientStart')?.value + ', ' + settingsForm.get('lightFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Dark Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header class=\"dark-theme-header\">\n <h3 class=\"card-title\">{{ messages().sectionDarkTheme }}</h3>\n <label class=\"dark-theme-toggle\">\n <kendo-switch formControlName=\"darkThemeEnabled\"></kendo-switch>\n <span>{{ messages().enableDarkTheme }}</span>\n </label>\n </kendo-card-header>\n @if (darkThemeEnabled()) {\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkHeaderGradientStart')?.value + ', ' + settingsForm.get('darkHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkFooterGradientStart')?.value + ', ' + settingsForm.get('darkFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n }\n </kendo-card>\n\n <div class=\"form-actions-bar\">\n <button\n kendoButton\n type=\"button\"\n themeColor=\"base\"\n [svgIcon]=\"undoIcon\"\n [disabled]=\"saving()\"\n (click)=\"onResetDefaults()\"\n >\n {{ messages().resetDefaults }}\n </button>\n <button\n kendoButton\n type=\"submit\"\n themeColor=\"primary\"\n [svgIcon]=\"saveIcon\"\n [disabled]=\"!settingsForm.valid || saving()\"\n >\n {{ messages().save }}\n </button>\n </div>\n </form>\n</div>\n","import { Routes } from '@angular/router';\n\n/**\n * Routes for the branding/settings UI. Mount under any path:\n *\n * ```ts\n * { path: 'settings', canActivate: [adminGuard], children: BRANDING_ROUTES }\n * ```\n *\n * The `SettingsPageComponent` is lazy-loaded on first navigation regardless of\n * how the host wires this — `loadComponent` returns a dynamic import.\n */\nexport const BRANDING_ROUTES: Routes = [\n {\n path: '',\n loadComponent: () =>\n import('./settings-page.component').then(\n (m) => m.SettingsPageComponent,\n ),\n },\n];\n","/*\n * Public API Surface of @meshmakers/octo-ui/branding-settings\n *\n * Heavy admin-only branding editor. Lives in its own secondary entry point so\n * host applications that only need the lightweight branding pieces (header\n * logo, theme switcher, services) — exposed by the primary `@meshmakers/octo-ui`\n * entry — do not pay for the form/Kendo modules pulled in by the editor itself.\n */\nexport * from './settings-page.component';\nexport * from './branding-settings.messages';\nexport * from './branding-settings.routes';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"meshmakers-octo-ui-branding-settings.mjs","sources":["../../../../projects/meshmakers/octo-ui/branding-settings/src/settings-page.component.ts","../../../../projects/meshmakers/octo-ui/branding-settings/src/settings-page.component.html","../../../../projects/meshmakers/octo-ui/branding-settings/src/branding-settings.routes.ts","../../../../projects/meshmakers/octo-ui/branding-settings/src/public-api.ts","../../../../projects/meshmakers/octo-ui/branding-settings/src/meshmakers-octo-ui-branding-settings.ts"],"sourcesContent":["import { Component, inject, input, OnInit, signal } from '@angular/core';\nimport {\n FormBuilder,\n FormControl,\n FormGroup,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport {\n BrandingData,\n BrandingDataSource,\n OCTO_BRANDING_DEFAULTS,\n ThemePalette,\n} from '@meshmakers/octo-ui/branding';\nimport { MessageService } from '@meshmakers/shared-services';\nimport { ButtonsModule } from '@progress/kendo-angular-buttons';\nimport { InputsModule } from '@progress/kendo-angular-inputs';\nimport { LabelModule } from '@progress/kendo-angular-label';\nimport { LayoutModule } from '@progress/kendo-angular-layout';\nimport { saveIcon, undoIcon, xIcon } from '@progress/kendo-svg-icons';\nimport { BrandingSettingsMessages } from './branding-settings.messages';\n\ntype LogoSlotName = 'header' | 'footer' | 'favicon';\n\ninterface LogoSlot {\n file: File | null;\n preview: string | null;\n cleared: boolean;\n}\n\nconst EMPTY_LOGO_SLOT: LogoSlot = {\n file: null,\n preview: null,\n cleared: false,\n};\n\n@Component({\n selector: 'mm-branding-settings',\n standalone: true,\n imports: [\n InputsModule,\n LabelModule,\n ButtonsModule,\n LayoutModule,\n ReactiveFormsModule,\n ],\n templateUrl: './settings-page.component.html',\n styleUrl: './settings-page.component.scss',\n})\nexport class SettingsPageComponent implements OnInit {\n readonly messages = input.required<BrandingSettingsMessages>();\n\n private readonly fb = inject(FormBuilder);\n private readonly branding = inject(BrandingDataSource);\n private readonly messageService = inject(MessageService);\n private readonly defaults = inject(OCTO_BRANDING_DEFAULTS);\n\n protected readonly saveIcon = saveIcon;\n protected readonly undoIcon = undoIcon;\n protected readonly xIcon = xIcon;\n\n protected readonly logoSlotNames: readonly LogoSlotName[] = [\n 'header',\n 'footer',\n 'favicon',\n ];\n\n protected readonly saving = signal(false);\n\n protected readonly settingsForm: FormGroup;\n\n private readonly slotStates = {\n header: signal<LogoSlot>({ ...EMPTY_LOGO_SLOT }),\n footer: signal<LogoSlot>({ ...EMPTY_LOGO_SLOT }),\n favicon: signal<LogoSlot>({ ...EMPTY_LOGO_SLOT }),\n } as const satisfies Record<LogoSlotName, unknown>;\n\n private readonly persistedUrls = {\n header: signal<string | null>(null),\n footer: signal<string | null>(null),\n favicon: signal<string | null>(null),\n } as const satisfies Record<LogoSlotName, unknown>;\n\n constructor() {\n const { lightTheme, darkTheme } = this.defaults;\n const dark = darkTheme ?? lightTheme;\n\n // Seeding color controls with valid hex defaults is required: kendo-colorpicker\n // binds as a ControlValueAccessor and doesn't handle initial empty strings\n // cleanly inside kendo-formfield.\n this.settingsForm = this.fb.group({\n appName: [this.defaults.appName, Validators.required],\n appTitle: [this.defaults.appTitle],\n\n lightPrimaryColor: [lightTheme.primaryColor, Validators.required],\n lightSecondaryColor: [lightTheme.secondaryColor, Validators.required],\n lightTertiaryColor: [lightTheme.tertiaryColor, Validators.required],\n lightNeutralColor: [lightTheme.neutralColor, Validators.required],\n lightBackgroundColor: [lightTheme.backgroundColor],\n lightHeaderGradientStart: [lightTheme.headerGradient.startColor],\n lightHeaderGradientEnd: [lightTheme.headerGradient.endColor],\n lightFooterGradientStart: [lightTheme.footerGradient.startColor],\n lightFooterGradientEnd: [lightTheme.footerGradient.endColor],\n\n darkThemeEnabled: [darkTheme !== null],\n\n darkPrimaryColor: [dark.primaryColor, Validators.required],\n darkSecondaryColor: [dark.secondaryColor, Validators.required],\n darkTertiaryColor: [dark.tertiaryColor, Validators.required],\n darkNeutralColor: [dark.neutralColor, Validators.required],\n darkBackgroundColor: [dark.backgroundColor],\n darkHeaderGradientStart: [dark.headerGradient.startColor],\n darkHeaderGradientEnd: [dark.headerGradient.endColor],\n darkFooterGradientStart: [dark.footerGradient.startColor],\n darkFooterGradientEnd: [dark.footerGradient.endColor],\n });\n }\n\n protected darkThemeEnabled(): boolean {\n return this.settingsForm.get('darkThemeEnabled')?.value === true;\n }\n\n async ngOnInit(): Promise<void> {\n try {\n await this.branding.load();\n } catch (error) {\n console.error('[SettingsPageComponent] Failed to load branding', error);\n this.messageService.showError(this.messages().loadError);\n return;\n }\n this.hydrate(this.branding.branding());\n }\n\n private readonly dragOverSlot = signal<LogoSlotName | null>(null);\n\n protected isDragOver(slot: LogoSlotName): boolean {\n return this.dragOverSlot() === slot;\n }\n\n protected onLogoSelected(slot: LogoSlotName, event: Event): void {\n const input = event.target;\n if (!(input instanceof HTMLInputElement)) return;\n const file = input.files?.[0] ?? null;\n this.applyLogoFile(slot, file);\n input.value = '';\n }\n\n protected onLogoDragOver(slot: LogoSlotName, event: DragEvent): void {\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n this.dragOverSlot.set(slot);\n }\n\n protected onLogoDragLeave(slot: LogoSlotName): void {\n if (this.dragOverSlot() === slot) this.dragOverSlot.set(null);\n }\n\n protected onLogoDropped(slot: LogoSlotName, event: DragEvent): void {\n event.preventDefault();\n this.dragOverSlot.set(null);\n const file = event.dataTransfer?.files?.[0];\n if (!file || !file.type.startsWith('image/')) return;\n this.applyLogoFile(slot, file);\n }\n\n private applyLogoFile(slot: LogoSlotName, file: File | null): void {\n if (!file) return;\n const reader = new FileReader();\n reader.onload = (): void => {\n const result = reader.result;\n this.slotStates[slot].set({\n file,\n preview: typeof result === 'string' ? result : null,\n cleared: false,\n });\n };\n reader.readAsDataURL(file);\n }\n\n protected clearLogo(slot: LogoSlotName): void {\n this.slotStates[slot].set({ file: null, preview: null, cleared: true });\n this.persistedUrls[slot].set(null);\n }\n\n protected previewUrl(slot: LogoSlotName): string | null {\n return this.slotStates[slot]().preview ?? this.persistedUrls[slot]();\n }\n\n protected async onSubmit(): Promise<void> {\n if (this.settingsForm.invalid) {\n this.settingsForm.markAllAsTouched();\n return;\n }\n this.saving.set(true);\n try {\n await this.branding.save({\n appName: this.strValue('appName'),\n appTitle: this.strValue('appTitle'),\n headerLogoFile: this.logoFileForSave('header'),\n footerLogoFile: this.logoFileForSave('footer'),\n faviconFile: this.logoFileForSave('favicon'),\n lightTheme: this.paletteFromForm('light'),\n darkTheme: this.darkThemeEnabled() ? this.paletteFromForm('dark') : null,\n });\n this.messageService.showInformation(this.messages().saveSuccess);\n this.hydrate(this.branding.branding());\n this.settingsForm.markAsPristine();\n } catch (error) {\n console.error('[SettingsPageComponent] Failed to save branding', error);\n this.messageService.showError(this.messages().saveError);\n } finally {\n this.saving.set(false);\n }\n }\n\n protected async onResetDefaults(): Promise<void> {\n this.saving.set(true);\n try {\n await this.branding.resetToDefaults();\n this.hydrate(this.branding.branding());\n this.settingsForm.markAsPristine();\n this.messageService.showInformation(this.messages().resetSuccess);\n } catch (error) {\n console.error('[SettingsPageComponent] Failed to reset branding', error);\n this.messageService.showError(this.messages().saveError);\n } finally {\n this.saving.set(false);\n }\n }\n\n private hydrate(data: BrandingData): void {\n this.persistedUrls.header.set(data.headerLogoUrl);\n this.persistedUrls.footer.set(data.footerLogoUrl);\n this.persistedUrls.favicon.set(data.faviconUrl);\n\n for (const slot of this.logoSlotNames) {\n this.slotStates[slot].set({ ...EMPTY_LOGO_SLOT });\n }\n\n const dark =\n data.darkTheme ?? this.defaults.darkTheme ?? this.defaults.lightTheme;\n\n this.settingsForm.patchValue({\n appName: data.appName,\n appTitle: data.appTitle,\n darkThemeEnabled: data.darkTheme !== null,\n\n lightPrimaryColor: data.lightTheme.primaryColor,\n lightSecondaryColor: data.lightTheme.secondaryColor,\n lightTertiaryColor: data.lightTheme.tertiaryColor,\n lightNeutralColor: data.lightTheme.neutralColor,\n lightBackgroundColor: data.lightTheme.backgroundColor,\n lightHeaderGradientStart: data.lightTheme.headerGradient.startColor,\n lightHeaderGradientEnd: data.lightTheme.headerGradient.endColor,\n lightFooterGradientStart: data.lightTheme.footerGradient.startColor,\n lightFooterGradientEnd: data.lightTheme.footerGradient.endColor,\n\n darkPrimaryColor: dark.primaryColor,\n darkSecondaryColor: dark.secondaryColor,\n darkTertiaryColor: dark.tertiaryColor,\n darkNeutralColor: dark.neutralColor,\n darkBackgroundColor: dark.backgroundColor,\n darkHeaderGradientStart: dark.headerGradient.startColor,\n darkHeaderGradientEnd: dark.headerGradient.endColor,\n darkFooterGradientStart: dark.footerGradient.startColor,\n darkFooterGradientEnd: dark.footerGradient.endColor,\n });\n }\n\n private logoFileForSave(slot: LogoSlotName): File | null | undefined {\n const state = this.slotStates[slot]();\n if (state.file) return state.file;\n if (state.cleared) return null;\n return undefined;\n }\n\n private strValue(name: string): string {\n const value = this.settingsForm.get(name)?.value;\n return typeof value === 'string' ? value : '';\n }\n\n private paletteFromForm(kind: 'light' | 'dark'): ThemePalette {\n return {\n primaryColor: this.strValue(`${kind}PrimaryColor`),\n secondaryColor: this.strValue(`${kind}SecondaryColor`),\n tertiaryColor: this.strValue(`${kind}TertiaryColor`),\n neutralColor: this.strValue(`${kind}NeutralColor`),\n backgroundColor: this.strValue(`${kind}BackgroundColor`),\n headerGradient: {\n startColor: this.strValue(`${kind}HeaderGradientStart`),\n endColor: this.strValue(`${kind}HeaderGradientEnd`),\n },\n footerGradient: {\n startColor: this.strValue(`${kind}FooterGradientStart`),\n endColor: this.strValue(`${kind}FooterGradientEnd`),\n },\n };\n }\n\n // Used with `[formControl]` (not `formControlName`) on kendo-colorpicker:\n // FormControl directive accepts the control instance directly and avoids\n // FormControlName's @Self() injection that historically tripped on the\n // colorpicker's forwardRef NG_VALUE_ACCESSOR. Goes through Reactive Forms\n // properly (tracks dirty/touched/validators), unlike the old [value] +\n // (valueChange) workaround.\n protected colorCtrl(controlName: string): FormControl<string> {\n return this.settingsForm.get(controlName) as FormControl<string>;\n }\n\n /**\n * Resolves a localized label for a given logo slot. The maco-app source used\n * dynamic translate-key concatenation (`'Settings_Logo_' + slot | translate`);\n * the library expresses the same idea by mapping slot names to fields on the\n * `BrandingSettingsMessages` interface.\n */\n protected logoLabel(slot: LogoSlotName): string {\n const m = this.messages();\n switch (slot) {\n case 'header':\n return m.logoHeader;\n case 'footer':\n return m.logoFooter;\n case 'favicon':\n return m.logoFavicon;\n }\n }\n}\n","<div class=\"settings-page\">\n <form [formGroup]=\"settingsForm\" (ngSubmit)=\"onSubmit()\">\n\n <!-- General -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionGeneral }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"form-row\">\n <kendo-formfield [title]=\"messages().appName\">\n <kendo-label [text]=\"messages().appName\" [optional]=\"false\" />\n <input kendoTextBox formControlName=\"appName\" [required]=\"true\" />\n <kendo-formerror>\n {{ messages().appName }} {{ messages().required }}\n </kendo-formerror>\n </kendo-formfield>\n <kendo-formfield [title]=\"messages().appTitle\">\n <kendo-label [text]=\"messages().appTitle\" [optional]=\"true\" />\n <input kendoTextBox formControlName=\"appTitle\" />\n </kendo-formfield>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Logos -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLogos }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"logo-upload-row\">\n @for (slot of logoSlotNames; track slot) {\n <div class=\"file-upload-section\">\n <label class=\"upload-label\" [attr.for]=\"'logo-' + slot\">\n {{ logoLabel(slot) }}\n </label>\n <div\n class=\"logo-dropzone\"\n [class.logo-dropzone--active]=\"isDragOver(slot)\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-label]=\"logoLabel(slot)\"\n (click)=\"logoInput.click()\"\n (keydown.enter)=\"logoInput.click()\"\n (keydown.space)=\"$event.preventDefault(); logoInput.click()\"\n (dragover)=\"onLogoDragOver(slot, $event)\"\n (dragleave)=\"onLogoDragLeave(slot)\"\n (drop)=\"onLogoDropped(slot, $event)\"\n >\n <span class=\"logo-dropzone__label\">\n {{ slot === 'favicon' ? messages().uploadFavicon : messages().uploadLogo }}\n </span>\n <input\n #logoInput\n type=\"file\"\n accept=\"image/*\"\n [id]=\"'logo-' + slot\"\n (change)=\"onLogoSelected(slot, $event)\"\n class=\"logo-dropzone__input\"\n />\n </div>\n @let url = previewUrl(slot);\n @if (url) {\n <div class=\"logo-preview\">\n <img [src]=\"url\" [alt]=\"logoLabel(slot) + ' preview'\" />\n <button\n kendoButton\n type=\"button\"\n fillMode=\"flat\"\n [svgIcon]=\"xIcon\"\n (click)=\"clearLogo(slot)\"\n [attr.aria-label]=\"messages().logoRemove\"\n ></button>\n </div>\n }\n </div>\n }\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Light Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header>\n <h3 class=\"card-title\">{{ messages().sectionLightTheme }}</h3>\n </kendo-card-header>\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightHeaderGradientStart')?.value + ', ' + settingsForm.get('lightHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('lightFooterGradientStart')?.value + ', ' + settingsForm.get('lightFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('lightFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n </kendo-card>\n\n <!-- Dark Theme -->\n <kendo-card class=\"settings-card\">\n <kendo-card-header class=\"dark-theme-header\">\n <h3 class=\"card-title\">{{ messages().sectionDarkTheme }}</h3>\n <label class=\"dark-theme-toggle\">\n <kendo-switch formControlName=\"darkThemeEnabled\"></kendo-switch>\n <span>{{ messages().enableDarkTheme }}</span>\n </label>\n </kendo-card-header>\n @if (darkThemeEnabled()) {\n <kendo-card-body>\n <div class=\"color-grid\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorPrimary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkPrimaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorSecondary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkSecondaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorTertiary }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkTertiaryColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorNeutral }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkNeutralColor')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().colorBackground }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkBackgroundColor')\"\n ></kendo-colorpicker>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientHeader }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkHeaderGradientStart')?.value + ', ' + settingsForm.get('darkHeaderGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkHeaderGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n\n <div class=\"gradient-section\">\n <h4 class=\"subsection-title\">{{ messages().gradientFooter }}</h4>\n <div class=\"gradient-row\">\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientStart }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientStart')\"\n ></kendo-colorpicker>\n </div>\n <div class=\"color-field gradient-preview-col\">\n <span class=\"color-label\" aria-hidden=\"true\">&nbsp;</span>\n <div\n class=\"gradient-preview\"\n [style.background]=\"'linear-gradient(to right, ' + settingsForm.get('darkFooterGradientStart')?.value + ', ' + settingsForm.get('darkFooterGradientEnd')?.value + ')'\"\n ></div>\n </div>\n <div class=\"color-field\">\n <label class=\"color-label\">{{ messages().gradientEnd }}</label>\n <kendo-colorpicker\n [formControl]=\"colorCtrl('darkFooterGradientEnd')\"\n ></kendo-colorpicker>\n </div>\n </div>\n </div>\n </kendo-card-body>\n }\n </kendo-card>\n\n <div class=\"form-actions-bar\">\n <button\n kendoButton\n type=\"button\"\n themeColor=\"base\"\n [svgIcon]=\"undoIcon\"\n [disabled]=\"saving()\"\n (click)=\"onResetDefaults()\"\n >\n {{ messages().resetDefaults }}\n </button>\n <button\n kendoButton\n type=\"submit\"\n themeColor=\"primary\"\n [svgIcon]=\"saveIcon\"\n [disabled]=\"!settingsForm.valid || saving()\"\n >\n {{ messages().save }}\n </button>\n </div>\n </form>\n</div>\n","import { Routes } from '@angular/router';\n\n/**\n * Routes for the branding/settings UI. Mount under any path:\n *\n * ```ts\n * { path: 'settings', canActivate: [adminGuard], children: BRANDING_ROUTES }\n * ```\n *\n * The `SettingsPageComponent` is lazy-loaded on first navigation regardless of\n * how the host wires this — `loadComponent` returns a dynamic import.\n */\nexport const BRANDING_ROUTES: Routes = [\n {\n path: '',\n loadComponent: () =>\n import('./settings-page.component').then(\n (m) => m.SettingsPageComponent,\n ),\n },\n];\n","/*\n * Public API Surface of @meshmakers/octo-ui/branding-settings\n *\n * Heavy admin-only branding editor. Lives in its own secondary entry point so\n * host applications that only need the lightweight branding pieces (header\n * logo, theme switcher, services) — exposed by the primary `@meshmakers/octo-ui`\n * entry — do not pay for the form/Kendo modules pulled in by the editor itself.\n */\nexport * from './settings-page.component';\nexport * from './branding-settings.messages';\nexport * from './branding-settings.routes';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -105,10 +105,10 @@ class CreateBrandingDtoGQL extends i1.Mutation {
105
105
  constructor(apollo) {
106
106
  super(apollo);
107
107
  }
108
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CreateBrandingDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
109
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CreateBrandingDtoGQL, providedIn: 'root' });
108
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: CreateBrandingDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
109
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: CreateBrandingDtoGQL, providedIn: 'root' });
110
110
  }
111
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CreateBrandingDtoGQL, decorators: [{
111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: CreateBrandingDtoGQL, decorators: [{
112
112
  type: Injectable,
113
113
  args: [{
114
114
  providedIn: 'root'
@@ -171,10 +171,10 @@ class GetBrandingDtoGQL extends i1.Query {
171
171
  constructor(apollo) {
172
172
  super(apollo);
173
173
  }
174
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetBrandingDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
175
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetBrandingDtoGQL, providedIn: 'root' });
174
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GetBrandingDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
175
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GetBrandingDtoGQL, providedIn: 'root' });
176
176
  }
177
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: GetBrandingDtoGQL, decorators: [{
177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GetBrandingDtoGQL, decorators: [{
178
178
  type: Injectable,
179
179
  args: [{
180
180
  providedIn: 'root'
@@ -233,10 +233,10 @@ class UpdateBrandingDtoGQL extends i1.Mutation {
233
233
  constructor(apollo) {
234
234
  super(apollo);
235
235
  }
236
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: UpdateBrandingDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
237
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: UpdateBrandingDtoGQL, providedIn: 'root' });
236
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: UpdateBrandingDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
237
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: UpdateBrandingDtoGQL, providedIn: 'root' });
238
238
  }
239
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: UpdateBrandingDtoGQL, decorators: [{
239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: UpdateBrandingDtoGQL, decorators: [{
240
240
  type: Injectable,
241
241
  args: [{
242
242
  providedIn: 'root'
@@ -469,10 +469,10 @@ class BrandingDataSource {
469
469
  const buffer = await file.arrayBuffer();
470
470
  return Array.from(new Uint8Array(buffer));
471
471
  }
472
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BrandingDataSource, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
473
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BrandingDataSource, providedIn: 'root' });
472
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BrandingDataSource, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
473
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BrandingDataSource, providedIn: 'root' });
474
474
  }
475
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BrandingDataSource, decorators: [{
475
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BrandingDataSource, decorators: [{
476
476
  type: Injectable,
477
477
  args: [{ providedIn: 'root' }]
478
478
  }] });
@@ -547,10 +547,10 @@ class AppTitleService extends TitleStrategy {
547
547
  }
548
548
  return breadcrumb;
549
549
  }
550
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AppTitleService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
551
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AppTitleService, providedIn: 'root' });
550
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AppTitleService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
551
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AppTitleService, providedIn: 'root' });
552
552
  }
553
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AppTitleService, decorators: [{
553
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AppTitleService, decorators: [{
554
554
  type: Injectable,
555
555
  args: [{ providedIn: 'root' }]
556
556
  }] });
@@ -653,10 +653,10 @@ class ThemeService {
653
653
  return (this.document.defaultView?.matchMedia?.('(prefers-color-scheme: dark)')
654
654
  .matches ?? false);
655
655
  }
656
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
657
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeService, providedIn: 'root' });
656
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
657
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeService, providedIn: 'root' });
658
658
  }
659
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeService, decorators: [{
659
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeService, decorators: [{
660
660
  type: Injectable,
661
661
  args: [{ providedIn: 'root' }]
662
662
  }], ctorParameters: () => [] });
@@ -687,10 +687,10 @@ class ThemeSwitcherComponent {
687
687
  return;
688
688
  this.themeService.setDark(!this.isDark());
689
689
  }
690
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
691
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: ThemeSwitcherComponent, isStandalone: true, selector: "mm-theme-switcher", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-pressed]=\"isDark()\"\n [disabled]=\"!available()\"\n (click)=\"onToggle()\"\n>\n <kendo-svg-icon [icon]=\"isDark() ? lightIcon : darkIcon\" />\n</button>\n", styles: [":host{display:inline-flex}button{appearance:none;background:transparent;border:0;padding:var(--kendo-spacing-2);cursor:pointer;color:inherit}button[disabled]{cursor:not-allowed;opacity:.5}button:focus-visible{outline:2px solid currentColor;outline-offset:2px}\n"], dependencies: [{ kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
690
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
691
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: ThemeSwitcherComponent, isStandalone: true, selector: "mm-theme-switcher", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-pressed]=\"isDark()\"\n [disabled]=\"!available()\"\n (click)=\"onToggle()\"\n>\n <kendo-svg-icon [icon]=\"isDark() ? lightIcon : darkIcon\" />\n</button>\n", styles: [":host{display:inline-flex}button{appearance:none;background:transparent;border:0;padding:var(--kendo-spacing-2);cursor:pointer;color:inherit}button[disabled]{cursor:not-allowed;opacity:.5}button:focus-visible{outline:2px solid currentColor;outline-offset:2px}\n"], dependencies: [{ kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
692
692
  }
693
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ThemeSwitcherComponent, decorators: [{
693
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ThemeSwitcherComponent, decorators: [{
694
694
  type: Component,
695
695
  args: [{ selector: 'mm-theme-switcher', standalone: true, imports: [SVGIconModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n type=\"button\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-pressed]=\"isDark()\"\n [disabled]=\"!available()\"\n (click)=\"onToggle()\"\n>\n <kendo-svg-icon [icon]=\"isDark() ? lightIcon : darkIcon\" />\n</button>\n", styles: [":host{display:inline-flex}button{appearance:none;background:transparent;border:0;padding:var(--kendo-spacing-2);cursor:pointer;color:inherit}button[disabled]{cursor:not-allowed;opacity:.5}button:focus-visible{outline:2px solid currentColor;outline-offset:2px}\n"] }]
696
696
  }], propDecorators: { messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }] } });
@@ -983,10 +983,10 @@ class BrandingApplicationService {
983
983
  const brightness = (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
984
984
  return brightness > 128 ? '#000000' : '#ffffff';
985
985
  }
986
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BrandingApplicationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
987
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BrandingApplicationService, providedIn: 'root' });
986
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BrandingApplicationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
987
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BrandingApplicationService, providedIn: 'root' });
988
988
  }
989
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: BrandingApplicationService, decorators: [{
989
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BrandingApplicationService, decorators: [{
990
990
  type: Injectable,
991
991
  args: [{ providedIn: 'root' }]
992
992
  }], ctorParameters: () => [] });