quang 20.4.6 → 20.5.1

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.
Files changed (44) hide show
  1. package/auth/index.d.ts +4 -5
  2. package/components/autocomplete/README.md +4 -1
  3. package/components/autocomplete/index.d.ts +264 -37
  4. package/components/select/index.d.ts +24 -3
  5. package/components/shared/index.d.ts +13 -1
  6. package/fesm2022/quang-auth.mjs +20 -20
  7. package/fesm2022/quang-auth.mjs.map +1 -1
  8. package/fesm2022/quang-components-autocomplete.mjs +641 -196
  9. package/fesm2022/quang-components-autocomplete.mjs.map +1 -1
  10. package/fesm2022/quang-components-checkbox.mjs +4 -4
  11. package/fesm2022/quang-components-checkbox.mjs.map +1 -1
  12. package/fesm2022/quang-components-date.mjs +16 -6
  13. package/fesm2022/quang-components-date.mjs.map +1 -1
  14. package/fesm2022/quang-components-input.mjs +4 -4
  15. package/fesm2022/quang-components-input.mjs.map +1 -1
  16. package/fesm2022/quang-components-paginator.mjs +14 -14
  17. package/fesm2022/quang-components-paginator.mjs.map +1 -1
  18. package/fesm2022/quang-components-select.mjs +70 -24
  19. package/fesm2022/quang-components-select.mjs.map +1 -1
  20. package/fesm2022/quang-components-shared.mjs +63 -50
  21. package/fesm2022/quang-components-shared.mjs.map +1 -1
  22. package/fesm2022/quang-components-table.mjs +4 -4
  23. package/fesm2022/quang-components-table.mjs.map +1 -1
  24. package/fesm2022/quang-components-wysiwyg.mjs +4 -4
  25. package/fesm2022/quang-components-wysiwyg.mjs.map +1 -1
  26. package/fesm2022/quang-device.mjs +3 -3
  27. package/fesm2022/quang-device.mjs.map +1 -1
  28. package/fesm2022/quang-loader.mjs +7 -7
  29. package/fesm2022/quang-loader.mjs.map +1 -1
  30. package/fesm2022/quang-overlay-modal.mjs +90 -12
  31. package/fesm2022/quang-overlay-modal.mjs.map +1 -1
  32. package/fesm2022/quang-overlay-popover.mjs +8 -8
  33. package/fesm2022/quang-overlay-popover.mjs.map +1 -1
  34. package/fesm2022/quang-overlay-shared.mjs +11 -11
  35. package/fesm2022/quang-overlay-shared.mjs.map +1 -1
  36. package/fesm2022/quang-overlay-toast.mjs +7 -7
  37. package/fesm2022/quang-overlay-toast.mjs.map +1 -1
  38. package/fesm2022/quang-overlay-tooltip.mjs +8 -8
  39. package/fesm2022/quang-overlay-tooltip.mjs.map +1 -1
  40. package/fesm2022/quang-translation.mjs +6 -6
  41. package/fesm2022/quang-translation.mjs.map +1 -1
  42. package/overlay/modal/index.d.ts +39 -5
  43. package/overlay/toast/index.d.ts +2 -3
  44. package/package.json +35 -35
@@ -1 +1 @@
1
- {"version":3,"file":"quang-components-wysiwyg.mjs","sources":["../../../projects/quang/components/wysiwyg/wysiwyg.component.ts","../../../projects/quang/components/wysiwyg/wysiwyg.component.html","../../../projects/quang/components/wysiwyg/quang-components-wysiwyg.ts"],"sourcesContent":["import { NgClass } from '@angular/common'\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n effect,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { AbstractControl, NG_VALUE_ACCESSOR, ValidationErrors, Validators } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { QuangTooltipDirective } from 'quang/overlay/tooltip'\nimport { filter, take } from 'rxjs'\nimport sunEditor from 'suneditor'\nimport SunEditorCore from 'suneditor/src/lib/core'\nimport { SunEditorOptions } from 'suneditor/src/options'\nimport plugins from 'suneditor/src/plugins'\n\nimport { QuangBaseComponent } from 'quang/components/shared'\n\nexport type QuangWysiwygOptions = SunEditorOptions\n\n@Component({\n selector: 'quang-wysiwyg',\n templateUrl: './wysiwyg.component.html',\n styleUrl: './wysiwyg.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangWysiwygComponent),\n multi: true,\n },\n ],\n imports: [TranslocoPipe, NgClass, QuangTooltipDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * WYSIWYG (What You See Is What You Get) component based on {@link https://github.com/JiHong88/SunEditor}.\n *\n * This component provides a rich text editor for users to create and edit HTML content.\n * It supports a wide range of formatting options.\n *\n * @usageNotes\n * The component allows you to show or hide buttons from the WYSIWYG editor.\n * By default, all the available buttons are shown in the editor bar.\n *\n * The height of the editor can be customized by setting the `minHeight` property. By default, it is `200px`.\n */\nexport class QuangWysiwygComponent extends QuangBaseComponent<string> implements AfterViewInit {\n _inputForWysiwyg = viewChild<ElementRef>('inputForWysiwyg')\n\n minHeight = input<string | undefined>('200px')\n\n font = input<boolean>(true)\n\n fontSize = input<boolean>(true)\n\n formatBlock = input<boolean>(true)\n\n paragraphStyle = input<boolean>(true)\n\n blockquote = input<boolean>(true)\n\n bold = input<boolean>(true)\n\n underline = input<boolean>(true)\n\n italic = input<boolean>(true)\n\n strike = input<boolean>(true)\n\n fontColor = input<boolean>(true)\n\n highlightColor = input<boolean>(true)\n\n textStyle = input<boolean>(true)\n\n removeFormat = input<boolean>(true)\n\n align = input<boolean>(true)\n\n list = input<boolean>(true)\n\n table = input<boolean>(true)\n\n link = input<boolean>(true)\n\n image = input<boolean>(true)\n\n fullScreen = input<boolean>(true)\n\n showBlocks = input<boolean>(true)\n\n onImageUploadError = input<(errorMessage: any, result: any, core: any) => boolean>()\n onFileDrop = input<(e: any, cleanData: any, maxCharCount: any, core: any) => boolean>()\n\n wysiwygOptions = input<QuangWysiwygOptions | undefined>(undefined)\n\n _sunEditorWysiwygInstance = signal<SunEditorCore | undefined>(undefined)\n _sunEditorWysiwygInstance$ = toObservable(this._sunEditorWysiwygInstance)\n\n changeDetectorRef = signal(inject(ChangeDetectorRef))\n\n _generateSunEditorWysiwygEffect = effect(() => {\n try {\n const inputForWysiwyg = this._inputForWysiwyg()?.nativeElement\n if (inputForWysiwyg) {\n const sunEditorOptions: SunEditorOptions = {\n plugins,\n defaultTag: 'div',\n buttonList: this._ngControl()?.control?.enabled && !this.isReadonly() ? [this.getButtonList()] : [],\n minHeight: this.minHeight(),\n width: '100%',\n ...(this.wysiwygOptions() ?? {}),\n }\n\n let sunEditorWysiwygInstance = this._sunEditorWysiwygInstance()\n const ngControl = this._ngControl()\n\n if (sunEditorWysiwygInstance) {\n if (ngControl?.control?.enabled) {\n sunEditorWysiwygInstance.enable()\n }\n sunEditorWysiwygInstance.setOptions(sunEditorOptions)\n } else {\n sunEditorWysiwygInstance = sunEditor.create(inputForWysiwyg, sunEditorOptions)\n this._sunEditorWysiwygInstance.set(sunEditorWysiwygInstance)\n }\n\n const imageUploadError = this.onImageUploadError()\n const onFileDrop = this.onFileDrop()\n\n if (imageUploadError && sunEditorWysiwygInstance) {\n sunEditorWysiwygInstance.onImageUploadError = imageUploadError\n }\n if (onFileDrop && sunEditorWysiwygInstance) {\n sunEditorWysiwygInstance.onDrop = onFileDrop\n }\n\n this.registerEvents()\n }\n } catch (_) {\n // we usually end up here when we are in a modal and then it starts in the right way\n }\n })\n\n STRIP_HTML_REGEX = /<[^>]*>/g\n\n registerEvents(): void {\n const sunEditorInstance = this._sunEditorWysiwygInstance()\n if (sunEditorInstance) {\n sunEditorInstance.onChange = (contents) => {\n this.onChangedHandler(contents)\n this.changeDetectorRef().markForCheck()\n }\n sunEditorInstance.onBlur = () => {\n this.onBlurHandler()\n }\n if (this._isDisabled()) {\n sunEditorInstance.disable()\n }\n }\n }\n\n override writeValue(val: string): void {\n super.writeValue(val)\n this._sunEditorWysiwygInstance$\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n filter((x) => !!x),\n take(1)\n )\n .subscribe((sunEditorWysiwygInstance) => {\n if (sunEditorWysiwygInstance) {\n try {\n sunEditorWysiwygInstance.setContents(val)\n } catch (_) {\n // we usually end up here when we are in a modal and then it starts in the right way\n }\n }\n })\n }\n\n validate(control: AbstractControl): ValidationErrors | null {\n if (control.hasValidator(Validators.required) && control.value?.replace(this.STRIP_HTML_REGEX, '') === '') {\n return { required: true }\n }\n return null\n }\n\n override onChangedHandler(value: string): void {\n super.onChangedHandler(value)\n const control = this._ngControl()\n if (control?.control) {\n if (this.validate(control.control)) control.control.setErrors(this.validate(control.control))\n }\n }\n\n getButtonList(): string[] {\n const buttonList: string[] = []\n if (this.font()) {\n buttonList.push('font')\n }\n if (this.fontSize()) {\n buttonList.push('fontSize')\n }\n if (this.formatBlock()) {\n buttonList.push('formatBlock')\n }\n if (this.paragraphStyle()) {\n buttonList.push('paragraphStyle')\n }\n if (this.blockquote()) {\n buttonList.push('blockquote')\n }\n if (this.bold()) {\n buttonList.push('bold')\n }\n if (this.underline()) {\n buttonList.push('underline')\n }\n if (this.italic()) {\n buttonList.push('italic')\n }\n if (this.strike()) {\n buttonList.push('strike')\n }\n if (this.fontColor()) {\n buttonList.push('fontColor')\n }\n if (this.highlightColor()) {\n buttonList.push('hiliteColor')\n }\n if (this.textStyle()) {\n buttonList.push('textStyle')\n }\n if (this.removeFormat()) {\n buttonList.push('removeFormat')\n }\n if (this.align()) {\n buttonList.push('align')\n }\n if (this.list()) {\n buttonList.push('list')\n }\n if (this.table()) {\n buttonList.push('table')\n }\n if (this.link()) {\n buttonList.push('link')\n }\n if (this.image()) {\n buttonList.push('image')\n }\n if (this.fullScreen()) {\n buttonList.push('fullScreen')\n }\n if (this.showBlocks()) {\n buttonList.push('showBlocks')\n }\n return buttonList\n }\n}\n","<div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label d-flex gap-2\"\n >\n <div>\n <span>{{ componentLabel() | transloco }}</span>\n <span [hidden]=\"!_isRequired()\">*</span>\n </div>\n @if (helpMessage() && helpMessageTooltip()) {\n <div [quangTooltip]=\"helpMessage() | transloco\">\n <ng-content select=\"[help-icon]\" />\n </div>\n }\n </label>\n }\n <div\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n class=\"input-wysiwyg-container is-invalid\"\n >\n <textarea\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_value()\"\n #inputForWysiwyg\n class=\"form-control\"\n ></textarea>\n </div>\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage() && !helpMessageTooltip()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quang-components-wysiwyg.mjs","sources":["../../../projects/quang/components/wysiwyg/wysiwyg.component.ts","../../../projects/quang/components/wysiwyg/wysiwyg.component.html","../../../projects/quang/components/wysiwyg/quang-components-wysiwyg.ts"],"sourcesContent":["import { NgClass } from '@angular/common'\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n effect,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { AbstractControl, NG_VALUE_ACCESSOR, ValidationErrors, Validators } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { QuangTooltipDirective } from 'quang/overlay/tooltip'\nimport { filter, take } from 'rxjs'\nimport sunEditor from 'suneditor'\nimport SunEditorCore from 'suneditor/src/lib/core'\nimport { SunEditorOptions } from 'suneditor/src/options'\nimport plugins from 'suneditor/src/plugins'\n\nimport { QuangBaseComponent } from 'quang/components/shared'\n\nexport type QuangWysiwygOptions = SunEditorOptions\n\n@Component({\n selector: 'quang-wysiwyg',\n templateUrl: './wysiwyg.component.html',\n styleUrl: './wysiwyg.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangWysiwygComponent),\n multi: true,\n },\n ],\n imports: [TranslocoPipe, NgClass, QuangTooltipDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * WYSIWYG (What You See Is What You Get) component based on {@link https://github.com/JiHong88/SunEditor}.\n *\n * This component provides a rich text editor for users to create and edit HTML content.\n * It supports a wide range of formatting options.\n *\n * @usageNotes\n * The component allows you to show or hide buttons from the WYSIWYG editor.\n * By default, all the available buttons are shown in the editor bar.\n *\n * The height of the editor can be customized by setting the `minHeight` property. By default, it is `200px`.\n */\nexport class QuangWysiwygComponent extends QuangBaseComponent<string> implements AfterViewInit {\n _inputForWysiwyg = viewChild<ElementRef>('inputForWysiwyg')\n\n minHeight = input<string | undefined>('200px')\n\n font = input<boolean>(true)\n\n fontSize = input<boolean>(true)\n\n formatBlock = input<boolean>(true)\n\n paragraphStyle = input<boolean>(true)\n\n blockquote = input<boolean>(true)\n\n bold = input<boolean>(true)\n\n underline = input<boolean>(true)\n\n italic = input<boolean>(true)\n\n strike = input<boolean>(true)\n\n fontColor = input<boolean>(true)\n\n highlightColor = input<boolean>(true)\n\n textStyle = input<boolean>(true)\n\n removeFormat = input<boolean>(true)\n\n align = input<boolean>(true)\n\n list = input<boolean>(true)\n\n table = input<boolean>(true)\n\n link = input<boolean>(true)\n\n image = input<boolean>(true)\n\n fullScreen = input<boolean>(true)\n\n showBlocks = input<boolean>(true)\n\n onImageUploadError = input<(errorMessage: any, result: any, core: any) => boolean>()\n onFileDrop = input<(e: any, cleanData: any, maxCharCount: any, core: any) => boolean>()\n\n wysiwygOptions = input<QuangWysiwygOptions | undefined>(undefined)\n\n _sunEditorWysiwygInstance = signal<SunEditorCore | undefined>(undefined)\n _sunEditorWysiwygInstance$ = toObservable(this._sunEditorWysiwygInstance)\n\n changeDetectorRef = signal(inject(ChangeDetectorRef))\n\n _generateSunEditorWysiwygEffect = effect(() => {\n try {\n const inputForWysiwyg = this._inputForWysiwyg()?.nativeElement\n if (inputForWysiwyg) {\n const sunEditorOptions: SunEditorOptions = {\n plugins,\n defaultTag: 'div',\n buttonList: this._ngControl()?.control?.enabled && !this.isReadonly() ? [this.getButtonList()] : [],\n minHeight: this.minHeight(),\n width: '100%',\n ...(this.wysiwygOptions() ?? {}),\n }\n\n let sunEditorWysiwygInstance = this._sunEditorWysiwygInstance()\n const ngControl = this._ngControl()\n\n if (sunEditorWysiwygInstance) {\n if (ngControl?.control?.enabled) {\n sunEditorWysiwygInstance.enable()\n }\n sunEditorWysiwygInstance.setOptions(sunEditorOptions)\n } else {\n sunEditorWysiwygInstance = sunEditor.create(inputForWysiwyg, sunEditorOptions)\n this._sunEditorWysiwygInstance.set(sunEditorWysiwygInstance)\n }\n\n const imageUploadError = this.onImageUploadError()\n const onFileDrop = this.onFileDrop()\n\n if (imageUploadError && sunEditorWysiwygInstance) {\n sunEditorWysiwygInstance.onImageUploadError = imageUploadError\n }\n if (onFileDrop && sunEditorWysiwygInstance) {\n sunEditorWysiwygInstance.onDrop = onFileDrop\n }\n\n this.registerEvents()\n }\n } catch (_) {\n // we usually end up here when we are in a modal and then it starts in the right way\n }\n })\n\n STRIP_HTML_REGEX = /<[^>]*>/g\n\n registerEvents(): void {\n const sunEditorInstance = this._sunEditorWysiwygInstance()\n if (sunEditorInstance) {\n sunEditorInstance.onChange = (contents) => {\n this.onChangedHandler(contents)\n this.changeDetectorRef().markForCheck()\n }\n sunEditorInstance.onBlur = () => {\n this.onBlurHandler()\n }\n if (this._isDisabled()) {\n sunEditorInstance.disable()\n }\n }\n }\n\n override writeValue(val: string): void {\n super.writeValue(val)\n this._sunEditorWysiwygInstance$\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n filter((x) => !!x),\n take(1)\n )\n .subscribe((sunEditorWysiwygInstance) => {\n if (sunEditorWysiwygInstance) {\n try {\n sunEditorWysiwygInstance.setContents(val)\n } catch (_) {\n // we usually end up here when we are in a modal and then it starts in the right way\n }\n }\n })\n }\n\n validate(control: AbstractControl): ValidationErrors | null {\n if (control.hasValidator(Validators.required) && control.value?.replace(this.STRIP_HTML_REGEX, '') === '') {\n return { required: true }\n }\n return null\n }\n\n override onChangedHandler(value: string): void {\n super.onChangedHandler(value)\n const control = this._ngControl()\n if (control?.control) {\n if (this.validate(control.control)) control.control.setErrors(this.validate(control.control))\n }\n }\n\n getButtonList(): string[] {\n const buttonList: string[] = []\n if (this.font()) {\n buttonList.push('font')\n }\n if (this.fontSize()) {\n buttonList.push('fontSize')\n }\n if (this.formatBlock()) {\n buttonList.push('formatBlock')\n }\n if (this.paragraphStyle()) {\n buttonList.push('paragraphStyle')\n }\n if (this.blockquote()) {\n buttonList.push('blockquote')\n }\n if (this.bold()) {\n buttonList.push('bold')\n }\n if (this.underline()) {\n buttonList.push('underline')\n }\n if (this.italic()) {\n buttonList.push('italic')\n }\n if (this.strike()) {\n buttonList.push('strike')\n }\n if (this.fontColor()) {\n buttonList.push('fontColor')\n }\n if (this.highlightColor()) {\n buttonList.push('hiliteColor')\n }\n if (this.textStyle()) {\n buttonList.push('textStyle')\n }\n if (this.removeFormat()) {\n buttonList.push('removeFormat')\n }\n if (this.align()) {\n buttonList.push('align')\n }\n if (this.list()) {\n buttonList.push('list')\n }\n if (this.table()) {\n buttonList.push('table')\n }\n if (this.link()) {\n buttonList.push('link')\n }\n if (this.image()) {\n buttonList.push('image')\n }\n if (this.fullScreen()) {\n buttonList.push('fullScreen')\n }\n if (this.showBlocks()) {\n buttonList.push('showBlocks')\n }\n return buttonList\n }\n}\n","<div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label d-flex gap-2\"\n >\n <div>\n <span>{{ componentLabel() | transloco }}</span>\n <span [hidden]=\"!_isRequired()\">*</span>\n </div>\n @if (helpMessage() && helpMessageTooltip()) {\n <div [quangTooltip]=\"helpMessage() | transloco\">\n <ng-content select=\"[help-icon]\" />\n </div>\n }\n </label>\n }\n <div\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n class=\"input-wysiwyg-container is-invalid\"\n >\n <textarea\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_value()\"\n #inputForWysiwyg\n class=\"form-control\"\n ></textarea>\n </div>\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage() && !helpMessageTooltip()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -24,10 +24,10 @@ class ResizeObservableService {
24
24
  widthResizeObservable(elem) {
25
25
  return this.resizeObservable(elem).pipe(map((entry) => entry.borderBoxSize[0].inlineSize), filter(Boolean));
26
26
  }
27
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: ResizeObservableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
28
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: ResizeObservableService, providedIn: 'root' }); }
27
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ResizeObservableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
28
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ResizeObservableService, providedIn: 'root' }); }
29
29
  }
30
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: ResizeObservableService, decorators: [{
30
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ResizeObservableService, decorators: [{
31
31
  type: Injectable,
32
32
  args: [{
33
33
  providedIn: 'root',
@@ -1 +1 @@
1
- {"version":3,"file":"quang-device.mjs","sources":["../../../projects/quang/device/resize-observable.service.ts","../../../projects/quang/device/quang-device.ts"],"sourcesContent":["import { Injectable } from '@angular/core'\n\nimport { NextObserver, Observable, Subscriber, filter, map, throttleTime } from 'rxjs'\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ResizeObservableService {\n private resizeObserver: ResizeObserver\n\n private notifiers: NextObserver<ResizeObserverEntry[]>[] = []\n\n constructor() {\n this.resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n this.notifiers.forEach((obs) => obs.next(entries))\n })\n }\n\n resizeObservable(elem: Element): Observable<ResizeObserverEntry> {\n this.resizeObserver.observe(elem)\n const newObserverCandidate = new Observable<ResizeObserverEntry[]>(\n (subscriber: Subscriber<ResizeObserverEntry[]>) => {\n this.notifiers.push(subscriber)\n\n return () => {\n const idx = this.notifiers.findIndex((val) => val === subscriber)\n this.notifiers.splice(idx, 1)\n this.resizeObserver.unobserve(elem)\n }\n }\n )\n\n return newObserverCandidate.pipe(\n map((entries) => entries.find((entry) => entry.target === elem)),\n filter(Boolean),\n throttleTime(30)\n )\n }\n\n widthResizeObservable(elem: Element): Observable<number> {\n return this.resizeObservable(elem).pipe(\n map((entry) => entry.borderBoxSize[0].inlineSize),\n filter(Boolean)\n )\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAOa,uBAAuB,CAAA;AAKlC,IAAA,WAAA,GAAA;QAFQ,IAAA,CAAA,SAAS,GAA0C,EAAE;QAG3D,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,CAAC,OAA8B,KAAI;AAC1E,YAAA,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACpD,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,gBAAgB,CAAC,IAAa,EAAA;AAC5B,QAAA,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC;QACjC,MAAM,oBAAoB,GAAG,IAAI,UAAU,CACzC,CAAC,UAA6C,KAAI;AAChD,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;AAE/B,YAAA,OAAO,MAAK;AACV,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,UAAU,CAAC;gBACjE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7B,gBAAA,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC;AACrC,YAAA,CAAC;AACH,QAAA,CAAC,CACF;AAED,QAAA,OAAO,oBAAoB,CAAC,IAAI,CAC9B,GAAG,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,EAChE,MAAM,CAAC,OAAO,CAAC,EACf,YAAY,CAAC,EAAE,CAAC,CACjB;IACH;AAEA,IAAA,qBAAqB,CAAC,IAAa,EAAA;AACjC,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CACrC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EACjD,MAAM,CAAC,OAAO,CAAC,CAChB;IACH;8GArCW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAvB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cAFtB,MAAM,EAAA,CAAA,CAAA;;2FAEP,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAHnC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACND;;AAEG;;;;"}
1
+ {"version":3,"file":"quang-device.mjs","sources":["../../../projects/quang/device/resize-observable.service.ts","../../../projects/quang/device/quang-device.ts"],"sourcesContent":["import { Injectable } from '@angular/core'\n\nimport { NextObserver, Observable, Subscriber, filter, map, throttleTime } from 'rxjs'\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ResizeObservableService {\n private resizeObserver: ResizeObserver\n\n private notifiers: NextObserver<ResizeObserverEntry[]>[] = []\n\n constructor() {\n this.resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {\n this.notifiers.forEach((obs) => obs.next(entries))\n })\n }\n\n resizeObservable(elem: Element): Observable<ResizeObserverEntry> {\n this.resizeObserver.observe(elem)\n const newObserverCandidate = new Observable<ResizeObserverEntry[]>(\n (subscriber: Subscriber<ResizeObserverEntry[]>) => {\n this.notifiers.push(subscriber)\n\n return () => {\n const idx = this.notifiers.findIndex((val) => val === subscriber)\n this.notifiers.splice(idx, 1)\n this.resizeObserver.unobserve(elem)\n }\n }\n )\n\n return newObserverCandidate.pipe(\n map((entries) => entries.find((entry) => entry.target === elem)),\n filter(Boolean),\n throttleTime(30)\n )\n }\n\n widthResizeObservable(elem: Element): Observable<number> {\n return this.resizeObservable(elem).pipe(\n map((entry) => entry.borderBoxSize[0].inlineSize),\n filter(Boolean)\n )\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;MAOa,uBAAuB,CAAA;AAKlC,IAAA,WAAA,GAAA;QAFQ,IAAA,CAAA,SAAS,GAA0C,EAAE;QAG3D,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,CAAC,OAA8B,KAAI;AAC1E,YAAA,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACpD,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,gBAAgB,CAAC,IAAa,EAAA;AAC5B,QAAA,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC;QACjC,MAAM,oBAAoB,GAAG,IAAI,UAAU,CACzC,CAAC,UAA6C,KAAI;AAChD,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;AAE/B,YAAA,OAAO,MAAK;AACV,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,UAAU,CAAC;gBACjE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7B,gBAAA,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC;AACrC,YAAA,CAAC;AACH,QAAA,CAAC,CACF;AAED,QAAA,OAAO,oBAAoB,CAAC,IAAI,CAC9B,GAAG,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,EAChE,MAAM,CAAC,OAAO,CAAC,EACf,YAAY,CAAC,EAAE,CAAC,CACjB;IACH;AAEA,IAAA,qBAAqB,CAAC,IAAa,EAAA;AACjC,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CACrC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EACjD,MAAM,CAAC,OAAO,CAAC,CAChB;IACH;+GArCW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAvB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,uBAAuB,cAFtB,MAAM,EAAA,CAAA,CAAA;;4FAEP,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAHnC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;ACND;;AAEG;;;;"}
@@ -17,10 +17,10 @@ class QuangLoaderService {
17
17
  hide() {
18
18
  patchState(this.loaderState, { count: this.loaderState().count - 1 });
19
19
  }
20
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangLoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
21
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangLoaderService, providedIn: 'root' }); }
20
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangLoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
21
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangLoaderService, providedIn: 'root' }); }
22
22
  }
23
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangLoaderService, decorators: [{
23
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangLoaderService, decorators: [{
24
24
  type: Injectable,
25
25
  args: [{
26
26
  providedIn: 'root',
@@ -69,13 +69,13 @@ class QuangLoaderComponent {
69
69
  this.showLoaderBuffer$ = toObservable(this.isLoading).pipe(map((isLoading) => (isLoading ? of(isLoading) : timer(this.showAtLeastFor()).pipe(map(() => isLoading)))), switchAll());
70
70
  this.showLoader = toSignal(this.showLoaderBuffer$);
71
71
  }
72
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
73
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.3", type: QuangLoaderComponent, isStandalone: true, selector: "quang-loader", inputs: { showAtLeastFor: { classPropertyName: "showAtLeastFor", publicName: "showAtLeastFor", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (showLoader()) {\n <div class=\"loader-container\">\n @if (!ref?.children?.length) {\n <span class=\"loader\"></span>\n }\n <div #ref>\n <ng-content></ng-content>\n </div>\n </div>\n}\n", styles: [":host{display:block}.loader-container{position:fixed;width:100%;height:100%;display:flex;top:0;left:0;background-color:#00000080;align-items:center;justify-content:center;z-index:99999}.loader-container .loader{width:48px;height:48px;border-radius:50%;display:inline-block;position:relative;border:3px solid;border-color:rgba(255,255,255,.7607843137) rgba(255,255,255,.7607843137) rgba(255,255,255,.7607843137) transparent;box-sizing:border-box;animation:rotation 1s linear infinite}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes rotationBack{0%{transform:rotate(0)}to{transform:rotate(-360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
72
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
73
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: QuangLoaderComponent, isStandalone: true, selector: "quang-loader", inputs: { showAtLeastFor: { classPropertyName: "showAtLeastFor", publicName: "showAtLeastFor", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (showLoader()) {\n <div class=\"loader-container\">\n @if (!ref?.children?.length) {\n <span class=\"loader\"></span>\n }\n <div #ref>\n <ng-content></ng-content>\n </div>\n </div>\n}\n", styles: [":host{display:block}.loader-container{position:fixed;width:100%;height:100%;display:flex;top:0;left:0;background-color:#00000080;align-items:center;justify-content:center;z-index:99999}.loader-container .loader{width:48px;height:48px;border-radius:50%;display:inline-block;position:relative;border:3px solid;border-color:rgba(255,255,255,.7607843137) rgba(255,255,255,.7607843137) rgba(255,255,255,.7607843137) transparent;box-sizing:border-box;animation:rotation 1s linear infinite}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes rotationBack{0%{transform:rotate(0)}to{transform:rotate(-360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
74
74
  }
75
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangLoaderComponent, decorators: [{
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangLoaderComponent, decorators: [{
76
76
  type: Component,
77
77
  args: [{ selector: 'quang-loader', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (showLoader()) {\n <div class=\"loader-container\">\n @if (!ref?.children?.length) {\n <span class=\"loader\"></span>\n }\n <div #ref>\n <ng-content></ng-content>\n </div>\n </div>\n}\n", styles: [":host{display:block}.loader-container{position:fixed;width:100%;height:100%;display:flex;top:0;left:0;background-color:#00000080;align-items:center;justify-content:center;z-index:99999}.loader-container .loader{width:48px;height:48px;border-radius:50%;display:inline-block;position:relative;border:3px solid;border-color:rgba(255,255,255,.7607843137) rgba(255,255,255,.7607843137) rgba(255,255,255,.7607843137) transparent;box-sizing:border-box;animation:rotation 1s linear infinite}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes rotationBack{0%{transform:rotate(0)}to{transform:rotate(-360deg)}}\n"] }]
78
- }] });
78
+ }], propDecorators: { showAtLeastFor: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAtLeastFor", required: false }] }] } });
79
79
 
80
80
  /**
81
81
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"quang-loader.mjs","sources":["../../../projects/quang/loader/loader.service.ts","../../../projects/quang/loader/loader.interceptor.ts","../../../projects/quang/loader/loader.component.ts","../../../projects/quang/loader/loader.component.html","../../../projects/quang/loader/loader-providers.ts","../../../projects/quang/loader/quang-loader.ts"],"sourcesContent":["import { Injectable, computed } from '@angular/core'\n\nimport { patchState, signalState } from '@ngrx/signals'\n\n@Injectable({\n providedIn: 'root',\n})\nexport class QuangLoaderService {\n private loaderState = signalState({ count: 0 })\n\n public isLoading = computed(() => this.loaderState.count() > 0)\n\n public show(): void {\n patchState(this.loaderState, { count: this.loaderState().count + 1 })\n }\n\n public hide(): void {\n patchState(this.loaderState, { count: this.loaderState().count - 1 })\n }\n}\n","import { HttpInterceptorFn } from '@angular/common/http'\nimport { InjectionToken, inject } from '@angular/core'\n\nimport { UrlData, getExcludedUrlsByMethod, isHttpMethod } from 'quang/shared'\nimport { finalize } from 'rxjs'\n\nimport { QuangLoaderService } from './loader.service'\n\nexport const LOADER_EXCLUDED_URLS = new InjectionToken<UrlData[]>('LOADER_EXCLUDED_URLS')\n\n/**\n * @deprecated\n * @see {@link LOADER_EXCLUDED_URLS}\n */\nexport const EXCLUDED_URL = LOADER_EXCLUDED_URLS\n\nexport const quangLoaderInterceptor: HttpInterceptorFn = (request, next) => {\n const excludedUrlsByMethod = getExcludedUrlsByMethod(inject(LOADER_EXCLUDED_URLS, { optional: true }) ?? [])\n const loaderService = inject(QuangLoaderService)\n if (!isHttpMethod(request.method)) {\n return next(request)\n }\n\n if (\n Array.from(excludedUrlsByMethod.get(request.method) ?? []).some((excludedUrl) =>\n request.url.match(excludedUrl.replace(/\\//g, '\\\\/'))\n )\n ) {\n return next(request)\n }\n\n loaderService.show()\n\n return next(request).pipe(\n finalize(() => {\n loaderService.hide()\n })\n )\n}\n","import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core'\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop'\n\nimport { map, of, switchAll, timer } from 'rxjs'\n\nimport { QuangLoaderService } from './loader.service'\n\n/**\n * @example\n * <quang-loader></quang-loader>\n *\n * @example\n * <quang-loader>\n * custom loader here\n * </quang-loader>\n */\n@Component({\n selector: 'quang-loader',\n imports: [],\n templateUrl: './loader.component.html',\n styleUrl: './loader.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class QuangLoaderComponent {\n /**\n * Minimum time (in milliseconds) to show the loader for\n * @default 500\n */\n showAtLeastFor = input<number>(500)\n\n private readonly loaderService = inject(QuangLoaderService)\n\n isLoading = this.loaderService.isLoading\n\n showLoaderBuffer$ = toObservable(this.isLoading).pipe(\n map((isLoading) => (isLoading ? of(isLoading) : timer(this.showAtLeastFor()).pipe(map(() => isLoading)))),\n switchAll()\n )\n\n showLoader = toSignal(this.showLoaderBuffer$)\n}\n","@if (showLoader()) {\n <div class=\"loader-container\">\n @if (!ref?.children?.length) {\n <span class=\"loader\"></span>\n }\n <div #ref>\n <ng-content></ng-content>\n </div>\n </div>\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core'\n\nimport { QuangFeature, QuangFeatureKind, quangFeature } from 'quang'\nimport { UrlData } from 'quang/shared'\n\nimport { LOADER_EXCLUDED_URLS } from './loader.interceptor'\n\n/**\n * @example\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideLoader([\n * {\n * url: 'assets',\n * method: 'GET',\n * },\n * ])\n * ]\n * }\n */\nexport function provideQuangLoaderExcludedUrls(excludedUrls: UrlData[]): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: LOADER_EXCLUDED_URLS,\n useValue: excludedUrls,\n },\n ])\n}\n\nexport function withLoaderExcludedUrls(excludedUrls: UrlData[]): QuangFeature<QuangFeatureKind.LoaderFeature> {\n return quangFeature(QuangFeatureKind.LoaderFeature, [provideQuangLoaderExcludedUrls(excludedUrls)])\n}\n\n/**\n * @deprecated\n * @see {@link provideQuangLoaderExcludedUrls}\n */\nexport const provideLoader = provideQuangLoaderExcludedUrls\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;MAOa,kBAAkB,CAAA;AAH/B,IAAA,WAAA,GAAA;QAIU,IAAA,CAAA,WAAW,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAExC,QAAA,IAAA,CAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,qDAAC;AAShE,IAAA;IAPQ,IAAI,GAAA;AACT,QAAA,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;IACvE;IAEO,IAAI,GAAA;AACT,QAAA,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;IACvE;8GAXW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cAFjB,MAAM,EAAA,CAAA,CAAA;;2FAEP,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAH9B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;MCEY,oBAAoB,GAAG,IAAI,cAAc,CAAY,sBAAsB;AAExF;;;AAGG;AACI,MAAM,YAAY,GAAG;MAEf,sBAAsB,GAAsB,CAAC,OAAO,EAAE,IAAI,KAAI;AACzE,IAAA,MAAM,oBAAoB,GAAG,uBAAuB,CAAC,MAAM,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAC5G,IAAA,MAAM,aAAa,GAAG,MAAM,CAAC,kBAAkB,CAAC;IAChD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;AACjC,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB;AAEA,IAAA,IACE,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,KAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CACrD,EACD;AACA,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB;IAEA,aAAa,CAAC,IAAI,EAAE;IAEpB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CACvB,QAAQ,CAAC,MAAK;QACZ,aAAa,CAAC,IAAI,EAAE;IACtB,CAAC,CAAC,CACH;AACH;;AC/BA;;;;;;;;AAQG;MAQU,oBAAoB,CAAA;AAPjC,IAAA,WAAA,GAAA;AAQE;;;AAGG;AACH,QAAA,IAAA,CAAA,cAAc,GAAG,KAAK,CAAS,GAAG,0DAAC;AAElB,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAE3D,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS;QAExC,IAAA,CAAA,iBAAiB,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CACnD,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC,EACzG,SAAS,EAAE,CACZ;AAED,QAAA,IAAA,CAAA,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAC9C,IAAA;8GAjBY,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,uOCvBjC,uNAUA,EAAA,MAAA,EAAA,CAAA,4nBAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FDaa,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAPhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,EAAA,OAAA,EACf,EAAE,EAAA,eAAA,EAGM,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,uNAAA,EAAA,MAAA,EAAA,CAAA,4nBAAA,CAAA,EAAA;;;AEdjD;;;;;;;;;;;;AAYG;AACG,SAAU,8BAA8B,CAAC,YAAuB,EAAA;AACpE,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,EAAE,oBAAoB;AAC7B,YAAA,QAAQ,EAAE,YAAY;AACvB,SAAA;AACF,KAAA,CAAC;AACJ;AAEM,SAAU,sBAAsB,CAAC,YAAuB,EAAA;IAC5D,OAAO,YAAY,yCAAiC,CAAC,8BAA8B,CAAC,YAAY,CAAC,CAAC,CAAC;AACrG;AAEA;;;AAGG;AACI,MAAM,aAAa,GAAG;;ACrC7B;;AAEG;;;;"}
1
+ {"version":3,"file":"quang-loader.mjs","sources":["../../../projects/quang/loader/loader.service.ts","../../../projects/quang/loader/loader.interceptor.ts","../../../projects/quang/loader/loader.component.ts","../../../projects/quang/loader/loader.component.html","../../../projects/quang/loader/loader-providers.ts","../../../projects/quang/loader/quang-loader.ts"],"sourcesContent":["import { Injectable, computed } from '@angular/core'\n\nimport { patchState, signalState } from '@ngrx/signals'\n\n@Injectable({\n providedIn: 'root',\n})\nexport class QuangLoaderService {\n private loaderState = signalState({ count: 0 })\n\n public isLoading = computed(() => this.loaderState.count() > 0)\n\n public show(): void {\n patchState(this.loaderState, { count: this.loaderState().count + 1 })\n }\n\n public hide(): void {\n patchState(this.loaderState, { count: this.loaderState().count - 1 })\n }\n}\n","import { HttpInterceptorFn } from '@angular/common/http'\nimport { InjectionToken, inject } from '@angular/core'\n\nimport { UrlData, getExcludedUrlsByMethod, isHttpMethod } from 'quang/shared'\nimport { finalize } from 'rxjs'\n\nimport { QuangLoaderService } from './loader.service'\n\nexport const LOADER_EXCLUDED_URLS = new InjectionToken<UrlData[]>('LOADER_EXCLUDED_URLS')\n\n/**\n * @deprecated\n * @see {@link LOADER_EXCLUDED_URLS}\n */\nexport const EXCLUDED_URL = LOADER_EXCLUDED_URLS\n\nexport const quangLoaderInterceptor: HttpInterceptorFn = (request, next) => {\n const excludedUrlsByMethod = getExcludedUrlsByMethod(inject(LOADER_EXCLUDED_URLS, { optional: true }) ?? [])\n const loaderService = inject(QuangLoaderService)\n if (!isHttpMethod(request.method)) {\n return next(request)\n }\n\n if (\n Array.from(excludedUrlsByMethod.get(request.method) ?? []).some((excludedUrl) =>\n request.url.match(excludedUrl.replace(/\\//g, '\\\\/'))\n )\n ) {\n return next(request)\n }\n\n loaderService.show()\n\n return next(request).pipe(\n finalize(() => {\n loaderService.hide()\n })\n )\n}\n","import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core'\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop'\n\nimport { map, of, switchAll, timer } from 'rxjs'\n\nimport { QuangLoaderService } from './loader.service'\n\n/**\n * @example\n * <quang-loader></quang-loader>\n *\n * @example\n * <quang-loader>\n * custom loader here\n * </quang-loader>\n */\n@Component({\n selector: 'quang-loader',\n imports: [],\n templateUrl: './loader.component.html',\n styleUrl: './loader.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class QuangLoaderComponent {\n /**\n * Minimum time (in milliseconds) to show the loader for\n * @default 500\n */\n showAtLeastFor = input<number>(500)\n\n private readonly loaderService = inject(QuangLoaderService)\n\n isLoading = this.loaderService.isLoading\n\n showLoaderBuffer$ = toObservable(this.isLoading).pipe(\n map((isLoading) => (isLoading ? of(isLoading) : timer(this.showAtLeastFor()).pipe(map(() => isLoading)))),\n switchAll()\n )\n\n showLoader = toSignal(this.showLoaderBuffer$)\n}\n","@if (showLoader()) {\n <div class=\"loader-container\">\n @if (!ref?.children?.length) {\n <span class=\"loader\"></span>\n }\n <div #ref>\n <ng-content></ng-content>\n </div>\n </div>\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core'\n\nimport { QuangFeature, QuangFeatureKind, quangFeature } from 'quang'\nimport { UrlData } from 'quang/shared'\n\nimport { LOADER_EXCLUDED_URLS } from './loader.interceptor'\n\n/**\n * @example\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideLoader([\n * {\n * url: 'assets',\n * method: 'GET',\n * },\n * ])\n * ]\n * }\n */\nexport function provideQuangLoaderExcludedUrls(excludedUrls: UrlData[]): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: LOADER_EXCLUDED_URLS,\n useValue: excludedUrls,\n },\n ])\n}\n\nexport function withLoaderExcludedUrls(excludedUrls: UrlData[]): QuangFeature<QuangFeatureKind.LoaderFeature> {\n return quangFeature(QuangFeatureKind.LoaderFeature, [provideQuangLoaderExcludedUrls(excludedUrls)])\n}\n\n/**\n * @deprecated\n * @see {@link provideQuangLoaderExcludedUrls}\n */\nexport const provideLoader = provideQuangLoaderExcludedUrls\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import * as i2 from '@angular/cdk/portal';
4
4
  import { PortalModule, CdkPortal } from '@angular/cdk/portal';
5
5
  import { NgStyle } from '@angular/common';
6
6
  import * as i0 from '@angular/core';
7
- import { output, input, computed, inject, DestroyRef, ViewChild, ChangeDetectionStrategy, Component, EnvironmentInjector, ApplicationRef, signal, createComponent, Injectable } from '@angular/core';
7
+ import { output, input, computed, inject, DestroyRef, ViewChild, ChangeDetectionStrategy, Component, InjectionToken, EnvironmentInjector, ApplicationRef, signal, Injector, createComponent, Injectable } from '@angular/core';
8
8
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
9
9
  import { Subject } from 'rxjs';
10
10
 
@@ -100,16 +100,43 @@ class QuangModalComponent {
100
100
  this.overlayRef?.detach();
101
101
  this.overlayRef?.dispose();
102
102
  }
103
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangModalComponent, deps: [{ token: i1.Overlay }], target: i0.ɵɵFactoryTarget.Component }); }
104
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.3", type: QuangModalComponent, isStandalone: true, selector: "quang-modal", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, containerClass: { classPropertyName: "containerClass", publicName: "containerClass", isSignal: true, isRequired: false, transformFunction: null }, animationMode: { classPropertyName: "animationMode", publicName: "animationMode", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, showBackdrop: { classPropertyName: "showBackdrop", publicName: "showBackdrop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { backdropClick: "backdropClick" }, viewQueries: [{ propertyName: "portal", first: true, predicate: CdkPortal, descendants: true }], ngImport: i0, template: "<ng-template cdkPortal>\n <div\n [ngStyle]=\"{\n '--quang-modal-panel-width': width(),\n '--quang-modal-panel-height': height(),\n '--quang-modal-panel-background': backgroundColor(),\n '--quang-modal-panel-padding': padding(),\n }\"\n class=\"dialog {{ containerClass() }} {{ animationClassEnter() }}\"\n >\n <div class=\"dialog__header\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"dialog__body\">\n <ng-content select=\"[body]\"></ng-content>\n </div>\n <div class=\"dialog__footer\">\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n </div>\n</ng-template>\n", styles: [".dialog{background-color:var(--quang-modal-panel-background, var(--bs-body-bg, initial));position:relative;display:flex;flex-direction:column;width:var(--quang-modal-panel-width);height:var(--quang-modal-panel-height);padding:var(--quang-modal-panel-padding)}.dialog__header{display:flex;flex-direction:column;width:100%}.dialog__body{flex:1;overflow:auto}.dialog__footer{display:flex;justify-content:flex-end}::ng-deep .cdk-global-scrollblock{overflow-y:auto}@keyframes left-to-right_enter{0%{transform:translate(-100%)}to{transform:translate(0)}}.left-to-right-enter-active{animation:left-to-right_enter .5s ease-in-out forwards}@keyframes right-to-left_enter{0%{transform:translate(100%)}to{transform:translate(0)}}.right-to-left-enter-active{animation:right-to-left_enter .5s ease-in-out forwards}@keyframes top-to-bottom_enter{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.top-to-bottom-enter-active{animation:top-to-bottom_enter .5s ease-in-out forwards}@keyframes bottom-to-top_enter{0%{transform:translateY(100%)}to{transform:translateY(0)}}.top-to-bottom-enter-active{animation:bottom-to-top_enter .5s ease-in-out forwards}@keyframes fade_enter{0%{opacity:0}to{opacity:1}}.fade-enter-active{animation:fade_enter .5s ease-in-out forwards}\n"], dependencies: [{ kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
103
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangModalComponent, deps: [{ token: i1.Overlay }], target: i0.ɵɵFactoryTarget.Component }); }
104
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: QuangModalComponent, isStandalone: true, selector: "quang-modal", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: true, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, containerClass: { classPropertyName: "containerClass", publicName: "containerClass", isSignal: true, isRequired: false, transformFunction: null }, animationMode: { classPropertyName: "animationMode", publicName: "animationMode", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, showBackdrop: { classPropertyName: "showBackdrop", publicName: "showBackdrop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { backdropClick: "backdropClick" }, viewQueries: [{ propertyName: "portal", first: true, predicate: CdkPortal, descendants: true }], ngImport: i0, template: "<ng-template cdkPortal>\n <div\n [ngStyle]=\"{\n '--quang-modal-panel-width': width(),\n '--quang-modal-panel-height': height(),\n '--quang-modal-panel-background': backgroundColor(),\n '--quang-modal-panel-padding': padding(),\n }\"\n class=\"dialog {{ containerClass() }} {{ animationClassEnter() }}\"\n >\n <div class=\"dialog__header\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"dialog__body\">\n <ng-content select=\"[body]\"></ng-content>\n </div>\n <div class=\"dialog__footer\">\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n </div>\n</ng-template>\n", styles: [".dialog{background-color:var(--quang-modal-panel-background, var(--bs-body-bg, initial));position:relative;display:flex;flex-direction:column;width:var(--quang-modal-panel-width);height:var(--quang-modal-panel-height);padding:var(--quang-modal-panel-padding)}.dialog__header{display:flex;flex-direction:column;width:100%}.dialog__body{flex:1;overflow:auto}.dialog__footer{display:flex;justify-content:flex-end}::ng-deep .cdk-global-scrollblock{overflow-y:auto}@keyframes left-to-right_enter{0%{transform:translate(-100%)}to{transform:translate(0)}}.left-to-right-enter-active{animation:left-to-right_enter .5s ease-in-out forwards}@keyframes right-to-left_enter{0%{transform:translate(100%)}to{transform:translate(0)}}.right-to-left-enter-active{animation:right-to-left_enter .5s ease-in-out forwards}@keyframes top-to-bottom_enter{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.top-to-bottom-enter-active{animation:top-to-bottom_enter .5s ease-in-out forwards}@keyframes bottom-to-top_enter{0%{transform:translateY(100%)}to{transform:translateY(0)}}.top-to-bottom-enter-active{animation:bottom-to-top_enter .5s ease-in-out forwards}@keyframes fade_enter{0%{opacity:0}to{opacity:1}}.fade-enter-active{animation:fade_enter .5s ease-in-out forwards}\n"], dependencies: [{ kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
105
105
  }
106
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangModalComponent, decorators: [{
106
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangModalComponent, decorators: [{
107
107
  type: Component,
108
108
  args: [{ selector: 'quang-modal', imports: [PortalModule, NgStyle], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template cdkPortal>\n <div\n [ngStyle]=\"{\n '--quang-modal-panel-width': width(),\n '--quang-modal-panel-height': height(),\n '--quang-modal-panel-background': backgroundColor(),\n '--quang-modal-panel-padding': padding(),\n }\"\n class=\"dialog {{ containerClass() }} {{ animationClassEnter() }}\"\n >\n <div class=\"dialog__header\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"dialog__body\">\n <ng-content select=\"[body]\"></ng-content>\n </div>\n <div class=\"dialog__footer\">\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n </div>\n</ng-template>\n", styles: [".dialog{background-color:var(--quang-modal-panel-background, var(--bs-body-bg, initial));position:relative;display:flex;flex-direction:column;width:var(--quang-modal-panel-width);height:var(--quang-modal-panel-height);padding:var(--quang-modal-panel-padding)}.dialog__header{display:flex;flex-direction:column;width:100%}.dialog__body{flex:1;overflow:auto}.dialog__footer{display:flex;justify-content:flex-end}::ng-deep .cdk-global-scrollblock{overflow-y:auto}@keyframes left-to-right_enter{0%{transform:translate(-100%)}to{transform:translate(0)}}.left-to-right-enter-active{animation:left-to-right_enter .5s ease-in-out forwards}@keyframes right-to-left_enter{0%{transform:translate(100%)}to{transform:translate(0)}}.right-to-left-enter-active{animation:right-to-left_enter .5s ease-in-out forwards}@keyframes top-to-bottom_enter{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.top-to-bottom-enter-active{animation:top-to-bottom_enter .5s ease-in-out forwards}@keyframes bottom-to-top_enter{0%{transform:translateY(100%)}to{transform:translateY(0)}}.top-to-bottom-enter-active{animation:bottom-to-top_enter .5s ease-in-out forwards}@keyframes fade_enter{0%{opacity:0}to{opacity:1}}.fade-enter-active{animation:fade_enter .5s ease-in-out forwards}\n"] }]
109
109
  }], ctorParameters: () => [{ type: i1.Overlay }], propDecorators: { portal: [{
110
110
  type: ViewChild,
111
111
  args: [CdkPortal]
112
- }] } });
112
+ }], backdropClick: [{ type: i0.Output, args: ["backdropClick"] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: true }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], containerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "containerClass", required: false }] }], animationMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "animationMode", required: false }] }], backgroundColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "backgroundColor", required: false }] }], showBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBackdrop", required: false }] }] } });
113
+
114
+ /**
115
+ * Injection token for the modal ID
116
+ */
117
+ const MODAL_ID = new InjectionToken('MODAL_ID');
118
+ /**
119
+ * Helper class to manage modal closure from within the modal component
120
+ */
121
+ class ModalRef {
122
+ constructor() {
123
+ this.modalService = inject(QuangModalService);
124
+ this.modalId = inject(MODAL_ID);
125
+ }
126
+ /**
127
+ * Close the modal with optional data
128
+ * @param data Optional data to pass when closing the modal (e.g., which button was clicked)
129
+ */
130
+ close(data) {
131
+ this.modalService.close(this.modalId, data);
132
+ }
133
+ /**
134
+ * Get the current modal ID
135
+ */
136
+ getId() {
137
+ return this.modalId;
138
+ }
139
+ }
113
140
 
114
141
  class QuangModalService {
115
142
  constructor() {
@@ -127,8 +154,19 @@ class QuangModalService {
127
154
  }
128
155
  showModal(component, options, componentInputs) {
129
156
  const id = this.generateId();
130
- // Create the content component instance first
157
+ // Create a Subject for this modal's close event
158
+ const closeSubject = new Subject();
159
+ // Create an injector that provides the modal ID and ModalRef
160
+ const modalInjector = Injector.create({
161
+ providers: [
162
+ { provide: MODAL_ID, useValue: id },
163
+ { provide: ModalRef, useClass: ModalRef },
164
+ ],
165
+ parent: this.environmentInjector,
166
+ });
167
+ // Create the content component instance first with the modal injector
131
168
  const contentRef = createComponent(component, {
169
+ elementInjector: modalInjector,
132
170
  environmentInjector: this.environmentInjector,
133
171
  });
134
172
  // Set component inputs if provided
@@ -164,7 +202,7 @@ class QuangModalService {
164
202
  modalRef.setInput('showBackdrop', options.showBackdrop);
165
203
  // Subscribe to backdrop click to close modal
166
204
  modalRef.instance.backdropClick.subscribe(() => {
167
- this.hideModal(id);
205
+ this.close(id);
168
206
  });
169
207
  // Attach components to the application
170
208
  this.appRef.attachView(contentRef.hostView);
@@ -176,10 +214,34 @@ class QuangModalService {
176
214
  id,
177
215
  modalRef,
178
216
  contentRef,
217
+ closeSubject,
179
218
  };
180
219
  this.modalInstances.update((instances) => [...instances, modalInstance]);
181
- return id;
220
+ return { id, closeCallback: closeSubject.asObservable() };
221
+ }
222
+ /**
223
+ * Closes a modal by its ID and emits optional data.
224
+ * @param id The ID of the modal to close.
225
+ * @param data Optional data to emit on close.
226
+ */
227
+ close(id, data) {
228
+ const instances = this.modalInstances();
229
+ const instance = instances.find((inst) => inst.id === id);
230
+ if (instance) {
231
+ // Emit the data through the subject before destroying
232
+ instance.closeSubject.next(data);
233
+ instance.closeSubject.complete();
234
+ // Remove the modal
235
+ this.hideModal(id);
236
+ }
237
+ else {
238
+ console.warn('[QuangModalService] Modal not found:', id);
239
+ }
182
240
  }
241
+ /**
242
+ * Hides a modal by its ID.
243
+ * @param id The ID of the modal to hide. If not provided, hides the last opened modal.
244
+ */
183
245
  hideModal(id) {
184
246
  if (id) {
185
247
  // Find and remove modal by id
@@ -187,22 +249,38 @@ class QuangModalService {
187
249
  const index = instances.findIndex((instance) => instance.id === id);
188
250
  if (index !== -1) {
189
251
  const modalToClose = instances[index];
252
+ // Complete the subject if not already completed
253
+ if (!modalToClose.closeSubject.closed) {
254
+ modalToClose.closeSubject.next(undefined);
255
+ modalToClose.closeSubject.complete();
256
+ }
190
257
  this.destroyModalInstance(modalToClose);
191
258
  this.modalInstances.update((instances) => instances.filter((_, i) => i !== index));
192
259
  // Emit modal closed event
193
260
  this.modalClosedSubject.next(id);
194
261
  }
262
+ else {
263
+ console.warn('[QuangModalService] Modal not found in instances:', id);
264
+ }
195
265
  }
196
266
  else {
197
267
  // Remove last modal (LIFO - Last In First Out)
198
268
  const instances = this.modalInstances();
199
269
  const lastModal = instances[instances.length - 1];
200
270
  if (lastModal) {
271
+ // Complete the subject if not already completed
272
+ if (!lastModal.closeSubject.closed) {
273
+ lastModal.closeSubject.next(undefined);
274
+ lastModal.closeSubject.complete();
275
+ }
201
276
  this.destroyModalInstance(lastModal);
202
277
  this.modalInstances.update((instances) => instances.slice(0, -1));
203
278
  // Emit modal closed event
204
279
  this.modalClosedSubject.next(lastModal.id);
205
280
  }
281
+ else {
282
+ console.warn('[QuangModalService] No modals to hide');
283
+ }
206
284
  }
207
285
  }
208
286
  destroyModalInstance(instance) {
@@ -223,10 +301,10 @@ class QuangModalService {
223
301
  this.idCounter.update((count) => count + 1);
224
302
  return `modal-${this.idCounter()}-${Date.now()}`;
225
303
  }
226
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
227
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangModalService, providedIn: 'root' }); }
304
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
305
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangModalService, providedIn: 'root' }); }
228
306
  }
229
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangModalService, decorators: [{
307
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangModalService, decorators: [{
230
308
  type: Injectable,
231
309
  args: [{
232
310
  providedIn: 'root',
@@ -237,5 +315,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImpor
237
315
  * Generated bundle index. Do not edit.
238
316
  */
239
317
 
240
- export { QuangModalComponent, QuangModalService };
318
+ export { MODAL_ID, ModalRef, QuangModalComponent, QuangModalService };
241
319
  //# sourceMappingURL=quang-overlay-modal.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"quang-overlay-modal.mjs","sources":["../../../projects/quang/overlay/modal/modal.component.ts","../../../projects/quang/overlay/modal/modal.component.html","../../../projects/quang/overlay/modal/modal.service.ts","../../../projects/quang/overlay/modal/quang-overlay-modal.ts"],"sourcesContent":["import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'\nimport { CdkPortal, PortalModule } from '@angular/cdk/portal'\nimport { NgStyle } from '@angular/common'\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n OnDestroy,\n ViewChild,\n computed,\n inject,\n input,\n output,\n} from '@angular/core'\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop'\n\nimport { ModalAnimationMode } from './models/ModalAnimationMode'\n\n@Component({\n selector: 'quang-modal',\n imports: [PortalModule, NgStyle],\n templateUrl: './modal.component.html',\n styleUrl: './modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Modal component that leverages Angular CDK's Overlay and Portal modules to create modals with flexible positioning and configurations.\n *\n * @usageNotes\n * The component can be shown by using its selector `quang-modal` with a boolean binded to the Angular directive `*ngIf`.\n *\n * Its structure is divided in 3 `ng-content` to set the header, body and footer.\n * Every section has its own selector and can be used to render custom content in a simple way.\n *\n * `header` section is placed on top, `footer` section is placed on bottom.\n *\n * @example\n * <quang-modal\n * (backdropClick)=\"closeModal()\"\n * *ngIf=\"showModal\"\n * position=\"right\"\n * >\n * <ng-container header>\n * <h2>Modal header</h2>\n * </ng-container>\n * <ng-container body>\n * <h3>Modal body</h3>\n * </ng-container>\n * <ng-container footer>\n * <h3>Modal footer</h3>\n * </ng-container>\n * </quang-modal>\n */\nexport class QuangModalComponent implements AfterViewInit, OnDestroy {\n @ViewChild(CdkPortal) public readonly portal?: CdkPortal\n\n backdropClick = output<void>()\n\n position = input.required<'right' | 'left' | 'center'>()\n\n height = input<string>('80vh')\n\n width = input<string>('80vw')\n\n padding = input<string>('0 1rem')\n\n containerClass = input<string>('')\n\n animationMode = input<ModalAnimationMode>()\n\n backgroundColor = input<string>()\n\n showBackdrop = input<boolean>(true)\n\n positionStrategy = computed(() => {\n switch (this.position()) {\n case 'right':\n return this.overlay.position().global().right().top()\n case 'left':\n return this.overlay.position().global().left().top()\n case 'center':\n default:\n return this.overlay.position().global().centerHorizontally().centerVertically()\n }\n })\n\n animationClassEnter = computed(() => {\n switch (this.animationMode()) {\n case 'SLIDE_FROM_LEFT_TO_RIGHT':\n return 'left-to-right-enter-active'\n case 'SLIDE_FROM_RIGHT_TO_LEFT':\n return 'right-to-left-enter-active'\n case 'SLIDE_TOP_TO_BOTTOM':\n return 'top-to-bottom-enter-active'\n case 'SLIDE_BOTTOM_TO_TOP':\n return 'top-to-bottom-enter-active'\n case 'FADE':\n return 'fade-enter-active'\n default:\n return ''\n }\n })\n\n private readonly destroyRef = inject(DestroyRef)\n\n private overlayConfig?: OverlayConfig\n\n private overlayRef?: OverlayRef\n\n constructor(private readonly overlay: Overlay) {}\n\n ngAfterViewInit(): void {\n this.overlayConfig = new OverlayConfig({\n hasBackdrop: true,\n positionStrategy: this.positionStrategy(),\n scrollStrategy: this.overlay.scrollStrategies.block(),\n backdropClass: this.showBackdrop() ? undefined : '',\n })\n this.overlayRef = this.overlay.create(this.overlayConfig)\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.backdropClick.emit()\n })\n this.overlayRef?.attach(this.portal)\n }\n\n ngOnDestroy(): void {\n this.closeModal()\n }\n\n closeModal(): void {\n this.overlayRef?.detach()\n this.overlayRef?.dispose()\n }\n}\n","<ng-template cdkPortal>\n <div\n [ngStyle]=\"{\n '--quang-modal-panel-width': width(),\n '--quang-modal-panel-height': height(),\n '--quang-modal-panel-background': backgroundColor(),\n '--quang-modal-panel-padding': padding(),\n }\"\n class=\"dialog {{ containerClass() }} {{ animationClassEnter() }}\"\n >\n <div class=\"dialog__header\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"dialog__body\">\n <ng-content select=\"[body]\"></ng-content>\n </div>\n <div class=\"dialog__footer\">\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n </div>\n</ng-template>\n","import {\n ApplicationRef,\n EnvironmentInjector,\n Injectable,\n Type,\n computed,\n createComponent,\n inject,\n signal,\n} from '@angular/core'\n\nimport { Subject } from 'rxjs'\n\nimport { QuangModalComponent } from './modal.component'\n\nimport { ModalInstance } from './models/ModalInstance'\nimport { ModalOptions } from './models/ModalOptions'\n\n@Injectable({\n providedIn: 'root',\n})\nexport class QuangModalService {\n private readonly environmentInjector = inject(EnvironmentInjector)\n private readonly appRef = inject(ApplicationRef)\n\n private modalInstances = signal<ModalInstance[]>([])\n private idCounter = signal(0)\n\n // Computed properties for easier access\n public modalCount = computed(() => this.modalInstances().length)\n public hasOpenModals = computed(() => this.modalInstances().length > 0)\n public modalIds = computed(() => this.modalInstances().map((instance) => instance.id))\n\n // Subject to emit when modals are closed\n private modalClosedSubject = new Subject<string>()\n public modalClosed$ = this.modalClosedSubject.asObservable()\n\n showModal<T = unknown>(component: Type<T>, options: ModalOptions, componentInputs?: Record<string, unknown>): string {\n const id = this.generateId()\n\n // Create the content component instance first\n const contentRef = createComponent(component, {\n environmentInjector: this.environmentInjector,\n })\n\n // Set component inputs if provided\n if (componentInputs) {\n Object.entries(componentInputs).forEach(([key, value]) => {\n contentRef.setInput(key, value)\n })\n }\n\n // Create the modal component instance with content projected in body slot\n const modalRef = createComponent(QuangModalComponent, {\n environmentInjector: this.environmentInjector,\n projectableNodes: [\n [], // header slot (empty)\n [contentRef.location.nativeElement], // body slot (content component)\n [], // footer slot (empty)\n ],\n })\n\n // Set modal inputs from options\n modalRef.setInput('position', options.position)\n if (options.height !== undefined) modalRef.setInput('height', options.height)\n if (options.width !== undefined) modalRef.setInput('width', options.width)\n if (options.padding !== undefined) modalRef.setInput('padding', options.padding)\n if (options.containerClass !== undefined) modalRef.setInput('containerClass', options.containerClass)\n if (options.animationMode !== undefined) modalRef.setInput('animationMode', options.animationMode)\n if (options.backgroundColor !== undefined) modalRef.setInput('backgroundColor', options.backgroundColor)\n if (options.showBackdrop !== undefined) modalRef.setInput('showBackdrop', options.showBackdrop)\n\n // Subscribe to backdrop click to close modal\n modalRef.instance.backdropClick.subscribe(() => {\n this.hideModal(id)\n })\n\n // Attach components to the application\n this.appRef.attachView(contentRef.hostView)\n this.appRef.attachView(modalRef.hostView)\n\n // Add modal to DOM\n document.body.appendChild(modalRef.location.nativeElement)\n\n // Store modal instance\n const modalInstance: ModalInstance = {\n id,\n modalRef,\n contentRef,\n }\n this.modalInstances.update((instances) => [...instances, modalInstance])\n\n return id\n }\n\n hideModal(id?: string): void {\n if (id) {\n // Find and remove modal by id\n const instances = this.modalInstances()\n const index = instances.findIndex((instance: ModalInstance) => instance.id === id)\n if (index !== -1) {\n const modalToClose = instances[index]\n this.destroyModalInstance(modalToClose)\n this.modalInstances.update((instances) => instances.filter((_, i) => i !== index))\n // Emit modal closed event\n this.modalClosedSubject.next(id)\n }\n } else {\n // Remove last modal (LIFO - Last In First Out)\n const instances = this.modalInstances()\n const lastModal = instances[instances.length - 1]\n if (lastModal) {\n this.destroyModalInstance(lastModal)\n this.modalInstances.update((instances) => instances.slice(0, -1))\n // Emit modal closed event\n this.modalClosedSubject.next(lastModal.id)\n }\n }\n }\n\n private destroyModalInstance(instance: ModalInstance): void {\n // Close the modal component (triggers overlay cleanup)\n instance.modalRef.instance.closeModal()\n\n // Detach from application\n this.appRef.detachView(instance.contentRef.hostView)\n this.appRef.detachView(instance.modalRef.hostView)\n\n // Remove from DOM if still attached\n if (instance.modalRef.location.nativeElement.parentNode) {\n instance.modalRef.location.nativeElement.parentNode.removeChild(instance.modalRef.location.nativeElement)\n }\n\n // Destroy component references\n instance.contentRef.destroy()\n instance.modalRef.destroy()\n }\n\n private generateId(): string {\n this.idCounter.update((count) => count + 1)\n return `modal-${this.idCounter()}-${Date.now()}`\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quang-overlay-modal.mjs","sources":["../../../projects/quang/overlay/modal/modal.component.ts","../../../projects/quang/overlay/modal/modal.component.html","../../../projects/quang/overlay/modal/modal-ref.ts","../../../projects/quang/overlay/modal/modal.service.ts","../../../projects/quang/overlay/modal/quang-overlay-modal.ts"],"sourcesContent":["import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'\nimport { CdkPortal, PortalModule } from '@angular/cdk/portal'\nimport { NgStyle } from '@angular/common'\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n OnDestroy,\n ViewChild,\n computed,\n inject,\n input,\n output,\n} from '@angular/core'\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop'\n\nimport { ModalAnimationMode } from './models/ModalAnimationMode'\n\n@Component({\n selector: 'quang-modal',\n imports: [PortalModule, NgStyle],\n templateUrl: './modal.component.html',\n styleUrl: './modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Modal component that leverages Angular CDK's Overlay and Portal modules to create modals with flexible positioning and configurations.\n *\n * @usageNotes\n * The component can be shown by using its selector `quang-modal` with a boolean binded to the Angular directive `*ngIf`.\n *\n * Its structure is divided in 3 `ng-content` to set the header, body and footer.\n * Every section has its own selector and can be used to render custom content in a simple way.\n *\n * `header` section is placed on top, `footer` section is placed on bottom.\n *\n * @example\n * <quang-modal\n * (backdropClick)=\"closeModal()\"\n * *ngIf=\"showModal\"\n * position=\"right\"\n * >\n * <ng-container header>\n * <h2>Modal header</h2>\n * </ng-container>\n * <ng-container body>\n * <h3>Modal body</h3>\n * </ng-container>\n * <ng-container footer>\n * <h3>Modal footer</h3>\n * </ng-container>\n * </quang-modal>\n */\nexport class QuangModalComponent implements AfterViewInit, OnDestroy {\n @ViewChild(CdkPortal) public readonly portal?: CdkPortal\n\n backdropClick = output<void>()\n\n position = input.required<'right' | 'left' | 'center'>()\n\n height = input<string>('80vh')\n\n width = input<string>('80vw')\n\n padding = input<string>('0 1rem')\n\n containerClass = input<string>('')\n\n animationMode = input<ModalAnimationMode>()\n\n backgroundColor = input<string>()\n\n showBackdrop = input<boolean>(true)\n\n positionStrategy = computed(() => {\n switch (this.position()) {\n case 'right':\n return this.overlay.position().global().right().top()\n case 'left':\n return this.overlay.position().global().left().top()\n case 'center':\n default:\n return this.overlay.position().global().centerHorizontally().centerVertically()\n }\n })\n\n animationClassEnter = computed(() => {\n switch (this.animationMode()) {\n case 'SLIDE_FROM_LEFT_TO_RIGHT':\n return 'left-to-right-enter-active'\n case 'SLIDE_FROM_RIGHT_TO_LEFT':\n return 'right-to-left-enter-active'\n case 'SLIDE_TOP_TO_BOTTOM':\n return 'top-to-bottom-enter-active'\n case 'SLIDE_BOTTOM_TO_TOP':\n return 'top-to-bottom-enter-active'\n case 'FADE':\n return 'fade-enter-active'\n default:\n return ''\n }\n })\n\n private readonly destroyRef = inject(DestroyRef)\n\n private overlayConfig?: OverlayConfig\n\n private overlayRef?: OverlayRef\n\n constructor(private readonly overlay: Overlay) {}\n\n ngAfterViewInit(): void {\n this.overlayConfig = new OverlayConfig({\n hasBackdrop: true,\n positionStrategy: this.positionStrategy(),\n scrollStrategy: this.overlay.scrollStrategies.block(),\n backdropClass: this.showBackdrop() ? undefined : '',\n })\n this.overlayRef = this.overlay.create(this.overlayConfig)\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.backdropClick.emit()\n })\n this.overlayRef?.attach(this.portal)\n }\n\n ngOnDestroy(): void {\n this.closeModal()\n }\n\n closeModal(): void {\n this.overlayRef?.detach()\n this.overlayRef?.dispose()\n }\n}\n","<ng-template cdkPortal>\n <div\n [ngStyle]=\"{\n '--quang-modal-panel-width': width(),\n '--quang-modal-panel-height': height(),\n '--quang-modal-panel-background': backgroundColor(),\n '--quang-modal-panel-padding': padding(),\n }\"\n class=\"dialog {{ containerClass() }} {{ animationClassEnter() }}\"\n >\n <div class=\"dialog__header\">\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div class=\"dialog__body\">\n <ng-content select=\"[body]\"></ng-content>\n </div>\n <div class=\"dialog__footer\">\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n </div>\n</ng-template>\n","import { InjectionToken, inject } from '@angular/core'\n\nimport { QuangModalService } from './modal.service'\n\n/**\n * Injection token for the modal ID\n */\nexport const MODAL_ID = new InjectionToken<string>('MODAL_ID')\n\n/**\n * Helper class to manage modal closure from within the modal component\n */\nexport class ModalRef {\n private readonly modalService = inject(QuangModalService)\n private readonly modalId = inject(MODAL_ID)\n\n /**\n * Close the modal with optional data\n * @param data Optional data to pass when closing the modal (e.g., which button was clicked)\n */\n close(data?: object): void {\n this.modalService.close(this.modalId, data)\n }\n\n /**\n * Get the current modal ID\n */\n getId(): string {\n return this.modalId\n }\n}\n","import {\n ApplicationRef,\n EnvironmentInjector,\n Injectable,\n Injector,\n Type,\n computed,\n createComponent,\n inject,\n signal,\n} from '@angular/core'\n\nimport { Observable, Subject } from 'rxjs'\n\nimport { QuangModalComponent } from './modal.component'\n\nimport { ModalOptions } from './models'\nimport { ModalInstance } from './models/ModalInstance'\n\nimport { MODAL_ID, ModalRef } from './modal-ref'\n\n@Injectable({\n providedIn: 'root',\n})\nexport class QuangModalService {\n private readonly environmentInjector = inject(EnvironmentInjector)\n private readonly appRef = inject(ApplicationRef)\n\n private modalInstances = signal<ModalInstance[]>([])\n private idCounter = signal(0)\n\n // Computed properties for easier access\n public modalCount = computed(() => this.modalInstances().length)\n public hasOpenModals = computed(() => this.modalInstances().length > 0)\n public modalIds = computed(() => this.modalInstances().map((instance) => instance.id))\n\n // Subject to emit when modals are closed\n private modalClosedSubject = new Subject<string>()\n public modalClosed$ = this.modalClosedSubject.asObservable()\n\n showModal<T = unknown>(\n component: Type<T>,\n options: ModalOptions,\n componentInputs?: Record<string, unknown>\n ): { id: string; closeCallback: Observable<object | undefined> } {\n const id = this.generateId()\n\n // Create a Subject for this modal's close event\n const closeSubject = new Subject<object | undefined>()\n\n // Create an injector that provides the modal ID and ModalRef\n const modalInjector = Injector.create({\n providers: [\n { provide: MODAL_ID, useValue: id },\n { provide: ModalRef, useClass: ModalRef },\n ],\n parent: this.environmentInjector,\n })\n\n // Create the content component instance first with the modal injector\n const contentRef = createComponent(component, {\n elementInjector: modalInjector,\n environmentInjector: this.environmentInjector,\n })\n\n // Set component inputs if provided\n if (componentInputs) {\n Object.entries(componentInputs).forEach(([key, value]) => {\n contentRef.setInput(key, value)\n })\n }\n\n // Create the modal component instance with content projected in body slot\n const modalRef = createComponent(QuangModalComponent, {\n environmentInjector: this.environmentInjector,\n projectableNodes: [\n [], // header slot (empty)\n [contentRef.location.nativeElement], // body slot (content component)\n [], // footer slot (empty)\n ],\n })\n\n // Set modal inputs from options\n modalRef.setInput('position', options.position)\n if (options.height !== undefined) modalRef.setInput('height', options.height)\n if (options.width !== undefined) modalRef.setInput('width', options.width)\n if (options.padding !== undefined) modalRef.setInput('padding', options.padding)\n if (options.containerClass !== undefined) modalRef.setInput('containerClass', options.containerClass)\n if (options.animationMode !== undefined) modalRef.setInput('animationMode', options.animationMode)\n if (options.backgroundColor !== undefined) modalRef.setInput('backgroundColor', options.backgroundColor)\n if (options.showBackdrop !== undefined) modalRef.setInput('showBackdrop', options.showBackdrop)\n\n // Subscribe to backdrop click to close modal\n modalRef.instance.backdropClick.subscribe(() => {\n this.close(id)\n })\n\n // Attach components to the application\n this.appRef.attachView(contentRef.hostView)\n this.appRef.attachView(modalRef.hostView)\n\n // Add modal to DOM\n document.body.appendChild(modalRef.location.nativeElement)\n\n // Store modal instance\n const modalInstance: ModalInstance = {\n id,\n modalRef,\n contentRef,\n closeSubject,\n }\n this.modalInstances.update((instances) => [...instances, modalInstance])\n return { id, closeCallback: closeSubject.asObservable() }\n }\n\n /**\n * Closes a modal by its ID and emits optional data.\n * @param id The ID of the modal to close.\n * @param data Optional data to emit on close.\n */\n close(id: string, data?: object): void {\n const instances = this.modalInstances()\n const instance = instances.find((inst) => inst.id === id)\n\n if (instance) {\n // Emit the data through the subject before destroying\n instance.closeSubject.next(data)\n instance.closeSubject.complete()\n\n // Remove the modal\n this.hideModal(id)\n } else {\n console.warn('[QuangModalService] Modal not found:', id)\n }\n }\n\n /**\n * Hides a modal by its ID.\n * @param id The ID of the modal to hide. If not provided, hides the last opened modal.\n */\n hideModal(id?: string): void {\n if (id) {\n // Find and remove modal by id\n const instances = this.modalInstances()\n const index = instances.findIndex((instance: ModalInstance) => instance.id === id)\n if (index !== -1) {\n const modalToClose = instances[index]\n // Complete the subject if not already completed\n if (!modalToClose.closeSubject.closed) {\n modalToClose.closeSubject.next(undefined)\n modalToClose.closeSubject.complete()\n }\n this.destroyModalInstance(modalToClose)\n this.modalInstances.update((instances) => instances.filter((_, i) => i !== index))\n // Emit modal closed event\n this.modalClosedSubject.next(id)\n } else {\n console.warn('[QuangModalService] Modal not found in instances:', id)\n }\n } else {\n // Remove last modal (LIFO - Last In First Out)\n const instances = this.modalInstances()\n const lastModal = instances[instances.length - 1]\n if (lastModal) {\n // Complete the subject if not already completed\n if (!lastModal.closeSubject.closed) {\n lastModal.closeSubject.next(undefined)\n lastModal.closeSubject.complete()\n }\n this.destroyModalInstance(lastModal)\n this.modalInstances.update((instances) => instances.slice(0, -1))\n // Emit modal closed event\n this.modalClosedSubject.next(lastModal.id)\n } else {\n console.warn('[QuangModalService] No modals to hide')\n }\n }\n }\n\n private destroyModalInstance(instance: ModalInstance): void {\n // Close the modal component (triggers overlay cleanup)\n instance.modalRef.instance.closeModal()\n\n // Detach from application\n this.appRef.detachView(instance.contentRef.hostView)\n this.appRef.detachView(instance.modalRef.hostView)\n\n // Remove from DOM if still attached\n if (instance.modalRef.location.nativeElement.parentNode) {\n instance.modalRef.location.nativeElement.parentNode.removeChild(instance.modalRef.location.nativeElement)\n }\n\n // Destroy component references\n instance.contentRef.destroy()\n instance.modalRef.destroy()\n }\n\n private generateId(): string {\n this.idCounter.update((count) => count + 1)\n return `modal-${this.idCounter()}-${Date.now()}`\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -38,13 +38,13 @@ class QuangPopoverComponent {
38
38
  }
39
39
  });
40
40
  }
41
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
42
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.3", type: QuangPopoverComponent, isStandalone: true, selector: "quang-popover", inputs: { overlayContent: { classPropertyName: "overlayContent", publicName: "overlayContent", isSignal: true, isRequired: false, transformFunction: null }, payload: { classPropertyName: "payload", publicName: "payload", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (overlayContent()) {\n <div\n [ngClass]=\"getPopoverPosition()\"\n class=\"popover-container\"\n >\n <ng-container\n [ngTemplateOutlet]=\"overlayContent()\"\n [ngTemplateOutletContext]=\"{\n $implicit: payload(),\n }\"\n ></ng-container>\n </div>\n}\n", styles: [":host{--bs-popover-border-width: 1px;--bs-popover-arrow-width: .5rem;--bs-popover-arrow-border: var(--bs-border-color, #000);--box-shadow-bg: rgba(0, 0, 0, .16)}.popover-container{box-shadow:var(--box-shadow-bg);background:var(--bs-body-bg, #fff);border:var(--bs-popover-border-width) solid var(--bs-border-color, #000);position:relative;padding:1rem;pointer-events:all}.popover-container.center-bottom:after,.popover-container.center-bottom:before{bottom:100%;left:50%;transform:translate(-50%)}.popover-container.start-bottom:after,.popover-container.start-bottom:before{bottom:100%;left:85%;transform:translate(-50%)}.popover-container.end-bottom:after,.popover-container.end-bottom:before{bottom:100%;left:15%;transform:translate(-50%)}.popover-container.center-top:after,.popover-container.center-top:before{top:100%;left:50%;transform:translate(-50%) rotate(180deg)}.popover-container.start-top:after,.popover-container.start-top:before{top:100%;left:85%;transform:translate(-50%) rotate(180deg)}.popover-container.end-top:after,.popover-container.end-top:before{top:100%;left:15%;transform:translate(-50%) rotate(180deg)}.popover-container.end-center:after,.popover-container.end-center:before{right:100%;top:50%;transform:translateY(-50%) rotate(270deg)}.popover-container.start-center:after,.popover-container.start-center:before{left:100%;top:50%;transform:translateY(-50%) rotate(90deg)}.popover-container:after,.popover-container:before{content:\"\";display:block;position:absolute;width:0;height:0;border-style:solid}.popover-container:after{border-color:transparent transparent var(--bs-body-bg, #fff) transparent;border-width:var(--bs-popover-arrow-width)}.popover-container:before{border-color:transparent transparent var(--bs-border-color, #000) transparent;border-width:calc(var(--bs-popover-arrow-width) + 1px)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
41
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
42
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: QuangPopoverComponent, isStandalone: true, selector: "quang-popover", inputs: { overlayContent: { classPropertyName: "overlayContent", publicName: "overlayContent", isSignal: true, isRequired: false, transformFunction: null }, payload: { classPropertyName: "payload", publicName: "payload", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (overlayContent()) {\n <div\n [ngClass]=\"getPopoverPosition()\"\n class=\"popover-container\"\n >\n <ng-container\n [ngTemplateOutlet]=\"overlayContent()\"\n [ngTemplateOutletContext]=\"{\n $implicit: payload(),\n }\"\n ></ng-container>\n </div>\n}\n", styles: [":host{--bs-popover-border-width: 1px;--bs-popover-arrow-width: .5rem;--bs-popover-arrow-border: var(--bs-border-color, #000);--box-shadow-bg: rgba(0, 0, 0, .16)}.popover-container{box-shadow:var(--box-shadow-bg);background:var(--bs-body-bg, #fff);border:var(--bs-popover-border-width) solid var(--bs-border-color, #000);position:relative;padding:1rem;pointer-events:all}.popover-container.center-bottom:after,.popover-container.center-bottom:before{bottom:100%;left:50%;transform:translate(-50%)}.popover-container.start-bottom:after,.popover-container.start-bottom:before{bottom:100%;left:85%;transform:translate(-50%)}.popover-container.end-bottom:after,.popover-container.end-bottom:before{bottom:100%;left:15%;transform:translate(-50%)}.popover-container.center-top:after,.popover-container.center-top:before{top:100%;left:50%;transform:translate(-50%) rotate(180deg)}.popover-container.start-top:after,.popover-container.start-top:before{top:100%;left:85%;transform:translate(-50%) rotate(180deg)}.popover-container.end-top:after,.popover-container.end-top:before{top:100%;left:15%;transform:translate(-50%) rotate(180deg)}.popover-container.end-center:after,.popover-container.end-center:before{right:100%;top:50%;transform:translateY(-50%) rotate(270deg)}.popover-container.start-center:after,.popover-container.start-center:before{left:100%;top:50%;transform:translateY(-50%) rotate(90deg)}.popover-container:after,.popover-container:before{content:\"\";display:block;position:absolute;width:0;height:0;border-style:solid}.popover-container:after{border-color:transparent transparent var(--bs-body-bg, #fff) transparent;border-width:var(--bs-popover-arrow-width)}.popover-container:before{border-color:transparent transparent var(--bs-border-color, #000) transparent;border-width:calc(var(--bs-popover-arrow-width) + 1px)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
43
43
  }
44
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangPopoverComponent, decorators: [{
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangPopoverComponent, decorators: [{
45
45
  type: Component,
46
46
  args: [{ selector: 'quang-popover', imports: [NgTemplateOutlet, NgClass], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (overlayContent()) {\n <div\n [ngClass]=\"getPopoverPosition()\"\n class=\"popover-container\"\n >\n <ng-container\n [ngTemplateOutlet]=\"overlayContent()\"\n [ngTemplateOutletContext]=\"{\n $implicit: payload(),\n }\"\n ></ng-container>\n </div>\n}\n", styles: [":host{--bs-popover-border-width: 1px;--bs-popover-arrow-width: .5rem;--bs-popover-arrow-border: var(--bs-border-color, #000);--box-shadow-bg: rgba(0, 0, 0, .16)}.popover-container{box-shadow:var(--box-shadow-bg);background:var(--bs-body-bg, #fff);border:var(--bs-popover-border-width) solid var(--bs-border-color, #000);position:relative;padding:1rem;pointer-events:all}.popover-container.center-bottom:after,.popover-container.center-bottom:before{bottom:100%;left:50%;transform:translate(-50%)}.popover-container.start-bottom:after,.popover-container.start-bottom:before{bottom:100%;left:85%;transform:translate(-50%)}.popover-container.end-bottom:after,.popover-container.end-bottom:before{bottom:100%;left:15%;transform:translate(-50%)}.popover-container.center-top:after,.popover-container.center-top:before{top:100%;left:50%;transform:translate(-50%) rotate(180deg)}.popover-container.start-top:after,.popover-container.start-top:before{top:100%;left:85%;transform:translate(-50%) rotate(180deg)}.popover-container.end-top:after,.popover-container.end-top:before{top:100%;left:15%;transform:translate(-50%) rotate(180deg)}.popover-container.end-center:after,.popover-container.end-center:before{right:100%;top:50%;transform:translateY(-50%) rotate(270deg)}.popover-container.start-center:after,.popover-container.start-center:before{left:100%;top:50%;transform:translateY(-50%) rotate(90deg)}.popover-container:after,.popover-container:before{content:\"\";display:block;position:absolute;width:0;height:0;border-style:solid}.popover-container:after{border-color:transparent transparent var(--bs-body-bg, #fff) transparent;border-width:var(--bs-popover-arrow-width)}.popover-container:before{border-color:transparent transparent var(--bs-border-color, #000) transparent;border-width:calc(var(--bs-popover-arrow-width) + 1px)}\n"] }]
47
- }] });
47
+ }], propDecorators: { overlayContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayContent", required: false }] }], payload: [{ type: i0.Input, args: [{ isSignal: true, alias: "payload", required: false }] }] } });
48
48
 
49
49
  class QuangPopoverDirective extends QuangBaseOverlayDirective {
50
50
  constructor() {
@@ -52,15 +52,15 @@ class QuangPopoverDirective extends QuangBaseOverlayDirective {
52
52
  this.targetComponentType = signal(QuangPopoverComponent, ...(ngDevMode ? [{ debugName: "targetComponentType" }] : []));
53
53
  this.content = input.required(...(ngDevMode ? [{ debugName: "content", alias: 'quangPopover' }] : [{ alias: 'quangPopover' }]));
54
54
  }
55
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangPopoverDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
56
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.3", type: QuangPopoverDirective, isStandalone: true, selector: "[quangPopover]", inputs: { content: { classPropertyName: "content", publicName: "quangPopover", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
55
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangPopoverDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
56
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.15", type: QuangPopoverDirective, isStandalone: true, selector: "[quangPopover]", inputs: { content: { classPropertyName: "content", publicName: "quangPopover", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
57
57
  }
58
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: QuangPopoverDirective, decorators: [{
58
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangPopoverDirective, decorators: [{
59
59
  type: Directive,
60
60
  args: [{
61
61
  selector: '[quangPopover]',
62
62
  }]
63
- }] });
63
+ }], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "quangPopover", required: true }] }] } });
64
64
 
65
65
  /**
66
66
  * Generated bundle index. Do not edit.