@m1z23r/ngx-ui 1.1.36 → 1.1.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,12 +45,20 @@ import { ButtonComponent } from '@m1z23r/ngx-ui';
45
45
  @Component({
46
46
  imports: [ButtonComponent],
47
47
  template: `
48
- <ui-button variant="primary" size="md" (clicked)="handleClick($event)">
48
+ <ui-button color="primary" size="md" (clicked)="handleClick($event)">
49
49
  Click me
50
50
  </ui-button>
51
51
 
52
- <ui-button variant="outline" [loading]="isLoading">
53
- Submit
52
+ <ui-button variant="outline" color="danger" [loading]="isLoading">
53
+ Delete
54
+ </ui-button>
55
+
56
+ <ui-button variant="ghost" color="secondary">
57
+ Cancel
58
+ </ui-button>
59
+
60
+ <ui-button variant="elevated" color="success">
61
+ Save
54
62
  </ui-button>
55
63
  `
56
64
  })
@@ -60,7 +68,8 @@ import { ButtonComponent } from '@m1z23r/ngx-ui';
60
68
 
61
69
  | Input | Type | Default | Description |
62
70
  |-------|------|---------|-------------|
63
- | `variant` | `'primary' \| 'secondary' \| 'outline' \| 'ghost'` | `'primary'` | Button style variant |
71
+ | `variant` | `'default' \| 'outline' \| 'ghost' \| 'elevated'` | `'default'` | Button style variant |
72
+ | `color` | `'primary' \| 'secondary' \| 'danger' \| 'success' \| 'warning'` | `'primary'` | Button color |
64
73
  | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
65
74
  | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | HTML button type |
66
75
  | `disabled` | `boolean` | `false` | Disable the button |
@@ -109,6 +118,9 @@ import { InputComponent } from '@m1z23r/ngx-ui';
109
118
  | `readonly` | `boolean` | `false` | Make input read-only |
110
119
  | `required` | `boolean` | `false` | Mark as required (shows asterisk) |
111
120
  | `id` | `string` | auto-generated | Custom input ID |
121
+ | `validators` | `ValidatorFn[]` | `[]` | Array of validator functions |
122
+ | `validatorFn` | `ValidatorFn \| null` | `null` | Single validator function |
123
+ | `showErrorsOn` | `'touched' \| 'dirty' \| 'always'` | `'touched'` | When to show validation errors |
112
124
 
113
125
  #### Two-way Binding
114
126
 
@@ -116,6 +128,26 @@ import { InputComponent } from '@m1z23r/ngx-ui';
116
128
  |-------|------|-------------|
117
129
  | `value` | `string \| number` | The input value |
118
130
 
131
+ #### Validation
132
+
133
+ The input component has built-in validation support:
134
+
135
+ ```typescript
136
+ // Computed properties
137
+ errors: Signal<ValidationError[]> // All current validation errors
138
+ isValid: Signal<boolean> // Whether input passes validation
139
+ isInvalid: Signal<boolean> // Whether input fails validation
140
+ errorMessage: Signal<string | null> // First error message
141
+ validationState: Signal<ValidationState> // Full validation state
142
+
143
+ // Methods
144
+ reset(): void // Reset value and validation state
145
+ markAsTouched(): void // Mark as touched
146
+ markAsDirty(): void // Mark as dirty
147
+ hasError(key: string): boolean // Check for specific error
148
+ getError(key: string): ValidationError | undefined // Get specific error
149
+ ```
150
+
119
151
  ---
120
152
 
121
153
  ### Table
@@ -399,7 +431,7 @@ import { ButtonComponent, LoadingDirective, LoadingService } from '@m1z23r/ngx-u
399
431
  <!-- These buttons automatically show loading when their identifier is active -->
400
432
  <ui-button uiLoading="login" (clicked)="login()">Login</ui-button>
401
433
  <ui-button uiLoading="submit" (clicked)="submit()">Submit</ui-button>
402
- <ui-button uiLoading="delete" variant="outline">Delete</ui-button>
434
+ <ui-button uiLoading="delete" variant="outline" color="danger">Delete</ui-button>
403
435
  `
404
436
  })
405
437
  export class MyComponent {
@@ -569,7 +601,7 @@ import { CircularProgressComponent } from '@m1z23r/ngx-ui';
569
601
  |-------|------|---------|-------------|
570
602
  | `value` | `number` | `0` | Progress value (0-100) |
571
603
  | `variant` | `'primary' \| 'success' \| 'warning' \| 'danger'` | `'primary'` | Color variant |
572
- | `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Circle size |
604
+ | `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Circle size |
573
605
  | `strokeWidth` | `number` | `4` | Stroke width in pixels |
574
606
  | `showLabel` | `boolean` | `false` | Show percentage in center |
575
607
  | `indeterminate` | `boolean` | `false` | Spinning animation |
@@ -791,6 +823,7 @@ import { TabsComponent, TabComponent } from '@m1z23r/ngx-ui';
791
823
  | `variant` | `'default' \| 'pills' \| 'underline'` | `'default'` | Tab style |
792
824
  | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Tab size |
793
825
  | `ariaLabel` | `string` | `''` | Accessibility label |
826
+ | `renderMode` | `'conditional' \| 'persistent'` | `'conditional'` | Tab content rendering strategy |
794
827
 
795
828
  ### Tabs Two-way Binding
796
829
 
@@ -798,12 +831,6 @@ import { TabsComponent, TabComponent } from '@m1z23r/ngx-ui';
798
831
  |-------|------|-------------|
799
832
  | `activeTab` | `string \| number` | Active tab ID or index |
800
833
 
801
- ### Tabs Outputs
802
-
803
- | Output | Type | Description |
804
- |--------|------|-------------|
805
- | `changed` | `string \| number` | Emitted when active tab changes |
806
-
807
834
  ### Tab Inputs
808
835
 
809
836
  | Input | Type | Default | Description |
@@ -876,10 +903,10 @@ export class MyComponent {
876
903
  | Method | Parameters | Returns | Description |
877
904
  |--------|------------|---------|-------------|
878
905
  | `show(config)` | `ToastConfig` | `ToastRef` | Show toast with full config |
879
- | `success(message, title?)` | `string, string?` | `ToastRef` | Success toast |
880
- | `error(message, title?)` | `string, string?` | `ToastRef` | Error toast |
881
- | `warning(message, title?)` | `string, string?` | `ToastRef` | Warning toast |
882
- | `info(message, title?)` | `string, string?` | `ToastRef` | Info toast |
906
+ | `success(message, title?, duration?)` | `string, string?, number?` | `ToastRef` | Success toast |
907
+ | `error(message, title?, duration?)` | `string, string?, number?` | `ToastRef` | Error toast |
908
+ | `warning(message, title?, duration?)` | `string, string?, number?` | `ToastRef` | Warning toast |
909
+ | `info(message, title?, duration?)` | `string, string?, number?` | `ToastRef` | Info toast |
883
910
  | `dismiss(id)` | `string` | `void` | Dismiss specific toast |
884
911
  | `dismissAll()` | - | `void` | Dismiss all toasts |
885
912
 
@@ -894,6 +921,7 @@ export class MyComponent {
894
921
  | `position` | `ToastPosition` | `'top-right'` | Screen position |
895
922
  | `dismissible` | `boolean` | `true` | Show close button |
896
923
  | `showProgress` | `boolean` | `true` | Show countdown bar |
924
+ | `maxVisible` | `number` | - | Max visible toasts at once |
897
925
 
898
926
  ### ToastPosition Values
899
927
 
@@ -927,7 +955,6 @@ import { PaginationComponent } from '@m1z23r/ngx-ui';
927
955
  [maxPages]="7"
928
956
  [showFirstLast]="true"
929
957
  size="md"
930
- (changed)="onPageChange($event)"
931
958
  />
932
959
  ```
933
960
 
@@ -947,12 +974,6 @@ import { PaginationComponent } from '@m1z23r/ngx-ui';
947
974
  |-------|------|-------------|
948
975
  | `page` | `number` | Current page (1-indexed) |
949
976
 
950
- ### Outputs
951
-
952
- | Output | Type | Description |
953
- |--------|------|-------------|
954
- | `changed` | `number` | Emitted when page changes |
955
-
956
977
  ### Features
957
978
 
958
979
  - **Smart truncation**: Shows ellipsis when there are many pages
@@ -981,7 +1002,7 @@ import { DialogService, DIALOG_DATA, DIALOG_REF, DialogRef, ModalComponent, Butt
981
1002
  <p>{{ data.message }}</p>
982
1003
 
983
1004
  <ng-container footer>
984
- <ui-button variant="outline" (clicked)="dialogRef.close(false)">Cancel</ui-button>
1005
+ <ui-button variant="outline" color="secondary" (clicked)="dialogRef.close(false)">Cancel</ui-button>
985
1006
  <ui-button (clicked)="dialogRef.close(true)">Confirm</ui-button>
986
1007
  </ng-container>
987
1008
  </ui-modal>
@@ -1021,7 +1042,7 @@ A wrapper component that provides the modal UI with backdrop, header, body, and
1021
1042
 
1022
1043
  <!-- Footer content (named slot) -->
1023
1044
  <ng-container footer>
1024
- <ui-button variant="outline" (clicked)="cancel()">Cancel</ui-button>
1045
+ <ui-button variant="outline" color="secondary" (clicked)="cancel()">Cancel</ui-button>
1025
1046
  <ui-button (clicked)="save()">Save</ui-button>
1026
1047
  </ng-container>
1027
1048
  </ui-modal>
@@ -1109,8 +1130,17 @@ All components use CSS custom properties for styling. Override these in your glo
1109
1130
 
1110
1131
  // Semantic colors
1111
1132
  --ui-success: #22c55e;
1133
+ --ui-success-hover: #16a34a;
1134
+ --ui-success-active: #15803d;
1135
+ --ui-success-text: #ffffff;
1112
1136
  --ui-danger: #ef4444;
1137
+ --ui-danger-hover: #dc2626;
1138
+ --ui-danger-active: #b91c1c;
1139
+ --ui-danger-text: #ffffff;
1113
1140
  --ui-warning: #f59e0b;
1141
+ --ui-warning-hover: #d97706;
1142
+ --ui-warning-active: #b45309;
1143
+ --ui-warning-text: #ffffff;
1114
1144
 
1115
1145
  // Background colors
1116
1146
  --ui-bg: #ffffff;
@@ -1132,6 +1162,7 @@ All components use CSS custom properties for styling. Override these in your glo
1132
1162
  --ui-radius-sm: 0.25rem;
1133
1163
  --ui-radius-md: 0.375rem;
1134
1164
  --ui-radius-lg: 0.5rem;
1165
+ --ui-radius-xl: 0.75rem;
1135
1166
 
1136
1167
  // Spacing
1137
1168
  --ui-spacing-xs: 0.25rem;
@@ -1146,10 +1177,13 @@ All components use CSS custom properties for styling. Override these in your glo
1146
1177
  --ui-navbar-height: 4rem;
1147
1178
  --ui-footer-height: 3rem;
1148
1179
 
1180
+ // Breakpoints
1181
+ --ui-breakpoint-mobile: 768px;
1182
+
1149
1183
  // Shadows
1150
1184
  --ui-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
1151
- --ui-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
1152
- --ui-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
1185
+ --ui-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
1186
+ --ui-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
1153
1187
 
1154
1188
  // Transitions
1155
1189
  --ui-transition-fast: 150ms ease;
@@ -1161,6 +1195,19 @@ All components use CSS custom properties for styling. Override these in your glo
1161
1195
  --ui-font-sm: 0.875rem;
1162
1196
  --ui-font-md: 1rem;
1163
1197
  --ui-font-lg: 1.125rem;
1198
+ --ui-font-xl: 1.25rem;
1199
+
1200
+ // Dropdown & Select
1201
+ --ui-dropdown-bg: var(--ui-bg);
1202
+ --ui-dropdown-border: var(--ui-border);
1203
+ --ui-dropdown-shadow: var(--ui-shadow-lg);
1204
+ --ui-dropdown-radius: var(--ui-radius-md);
1205
+ --ui-dropdown-max-height: 300px;
1206
+
1207
+ // Option/Item states
1208
+ --ui-option-hover-bg: var(--ui-bg-hover);
1209
+ --ui-option-selected-bg: color-mix(in srgb, var(--ui-primary) 10%, transparent);
1210
+ --ui-option-selected-text: var(--ui-primary);
1164
1211
  }
1165
1212
  ```
1166
1213
 
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, PLATFORM_ID, signal, Injectable, computed, InjectionToken, ApplicationRef, EnvironmentInjector, createComponent, Injector, input, output, ChangeDetectionStrategy, Component, ElementRef, HostListener, effect, Directive, model, Pipe, contentChildren, TemplateRef, contentChild, ViewChild, viewChild, afterRenderEffect, DestroyRef } from '@angular/core';
3
- import { isPlatformBrowser, NgTemplateOutlet, NgComponentOutlet, DOCUMENT, DecimalPipe } from '@angular/common';
3
+ import { isPlatformBrowser, DOCUMENT, NgTemplateOutlet, NgComponentOutlet, DecimalPipe } from '@angular/common';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { FormsModule } from '@angular/forms';
6
6
 
@@ -378,6 +378,8 @@ const DEFAULT_DIALOG_CONFIG = {
378
378
  class DialogService {
379
379
  appRef = inject(ApplicationRef);
380
380
  injector = inject(EnvironmentInjector);
381
+ document = inject(DOCUMENT);
382
+ platformId = inject(PLATFORM_ID);
381
383
  /**
382
384
  * Opens a dialog with the specified component.
383
385
  *
@@ -397,7 +399,9 @@ class DialogService {
397
399
  const hostElement = componentRef.location.nativeElement;
398
400
  hostElement.dataset['dialogConfig'] = JSON.stringify(mergedConfig);
399
401
  this.appRef.attachView(componentRef.hostView);
400
- document.body.appendChild(hostElement);
402
+ if (isPlatformBrowser(this.platformId)) {
403
+ this.document.body.appendChild(hostElement);
404
+ }
401
405
  return dialogRef;
402
406
  }
403
407
  destroy(componentRef) {
@@ -550,6 +554,8 @@ const TOAST_DATA = new InjectionToken('TOAST_DATA');
550
554
  class ToastService {
551
555
  appRef = inject(ApplicationRef);
552
556
  injector = inject(EnvironmentInjector);
557
+ document = inject(DOCUMENT);
558
+ platformId = inject(PLATFORM_ID);
553
559
  containerRef = null;
554
560
  toasts = signal([], ...(ngDevMode ? [{ debugName: "toasts" }] : []));
555
561
  toastRefs = new Map();
@@ -658,7 +664,9 @@ class ToastService {
658
664
  });
659
665
  this.updateContainer();
660
666
  this.appRef.attachView(this.containerRef.hostView);
661
- document.body.appendChild(this.containerRef.location.nativeElement);
667
+ if (isPlatformBrowser(this.platformId)) {
668
+ this.document.body.appendChild(this.containerRef.location.nativeElement);
669
+ }
662
670
  }
663
671
  updateContainer() {
664
672
  if (!this.containerRef)
@@ -922,6 +930,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
922
930
  class ModalComponent {
923
931
  dialogRef = inject(DIALOG_REF, { optional: true });
924
932
  elementRef = inject(ElementRef);
933
+ /** Tracks if mousedown started on the backdrop (to prevent close on drag-out) */
934
+ mouseDownOnBackdrop = signal(false, ...(ngDevMode ? [{ debugName: "mouseDownOnBackdrop" }] : []));
925
935
  /** Title displayed in the modal header */
926
936
  title = input(...(ngDevMode ? [undefined, { debugName: "title" }] : []));
927
937
  /** Modal size preset */
@@ -951,10 +961,17 @@ class ModalComponent {
951
961
  this.close();
952
962
  }
953
963
  }
964
+ onBackdropMouseDown(event) {
965
+ this.mouseDownOnBackdrop.set(event.target === event.currentTarget);
966
+ }
954
967
  onBackdropClick(event) {
955
- if (event.target === event.currentTarget && this.closeOnBackdropClick()) {
968
+ // Only close if both mousedown AND mouseup happened on the backdrop
969
+ if (this.mouseDownOnBackdrop() &&
970
+ event.target === event.currentTarget &&
971
+ this.closeOnBackdropClick()) {
956
972
  this.close();
957
973
  }
974
+ this.mouseDownOnBackdrop.set(false);
958
975
  }
959
976
  close() {
960
977
  this.dialogRef?.close();
@@ -967,11 +984,11 @@ class ModalComponent {
967
984
  return classes.join(' ');
968
985
  }
969
986
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
970
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: ModalComponent, isStandalone: true, selector: "ui-modal", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClick: { classPropertyName: "closeOnBackdropClick", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onEscapePress()" } }, ngImport: i0, template: "<div class=\"ui-modal__backdrop\" (click)=\"onBackdropClick($event)\">\n <div\n class=\"ui-modal__container\"\n [class]=\"containerClasses()\"\n [style.width]=\"width()\"\n [style.max-width]=\"maxWidth()\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n @if (title()) {\n <div class=\"ui-modal__header\">\n <h2 class=\"ui-modal__title\">{{ title() }}</h2>\n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"ui-modal__close\"\n aria-label=\"Close\"\n (click)=\"close()\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n </button>\n }\n </div>\n }\n\n <div class=\"ui-modal__body\">\n <ng-content />\n </div>\n\n <div class=\"ui-modal__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n </div>\n</div>\n", styles: [".ui-modal__backdrop{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:var(--ui-spacing-md);background-color:#00000080;animation:fadeIn var(--ui-transition-fast)}.ui-modal__container{position:relative;display:flex;flex-direction:column;max-height:calc(100vh - var(--ui-spacing-xl) * 2);background-color:var(--ui-bg);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-shadow-lg);animation:slideIn var(--ui-transition-normal)}.ui-modal--sm{max-width:400px}.ui-modal--md{max-width:560px}.ui-modal--lg{max-width:800px}.ui-modal--xl{max-width:1140px}.ui-modal--full{max-width:calc(100vw - var(--ui-spacing-xl) * 2);max-height:calc(100vh - var(--ui-spacing-xl) * 2)}.ui-modal__header{display:flex;align-items:center;justify-content:space-between;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-bottom:1px solid var(--ui-border)}.ui-modal__title{margin:0;font-size:var(--ui-font-lg);font-weight:600;color:var(--ui-text)}.ui-modal__close{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;margin:calc(var(--ui-spacing-sm) * -1);color:var(--ui-text-muted);background:transparent;border:none;border-radius:var(--ui-radius-sm);cursor:pointer;transition:all var(--ui-transition-fast)}.ui-modal__close:hover{color:var(--ui-text);background-color:var(--ui-bg-hover)}.ui-modal__close:focus-visible{outline:2px solid var(--ui-primary);outline-offset:2px}.ui-modal__body{flex:1;padding:var(--ui-spacing-lg);overflow-y:auto}.ui-modal__footer{display:flex;gap:var(--ui-spacing-sm);justify-content:flex-end;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-top:1px solid var(--ui-border)}.ui-modal__footer:empty{display:none}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-16px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
987
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: ModalComponent, isStandalone: true, selector: "ui-modal", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClick: { classPropertyName: "closeOnBackdropClick", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onEscapePress()" } }, ngImport: i0, template: "<div class=\"ui-modal__backdrop\" (mousedown)=\"onBackdropMouseDown($event)\" (click)=\"onBackdropClick($event)\">\n <div\n class=\"ui-modal__container\"\n [class]=\"containerClasses()\"\n [style.width]=\"width()\"\n [style.max-width]=\"maxWidth()\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n @if (title()) {\n <div class=\"ui-modal__header\">\n <h2 class=\"ui-modal__title\">{{ title() }}</h2>\n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"ui-modal__close\"\n aria-label=\"Close\"\n (click)=\"close()\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n </button>\n }\n </div>\n }\n\n <div class=\"ui-modal__body\">\n <ng-content />\n </div>\n\n <div class=\"ui-modal__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n </div>\n</div>\n", styles: [".ui-modal__backdrop{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:var(--ui-spacing-md);background-color:#00000080;animation:fadeIn var(--ui-transition-fast)}.ui-modal__container{position:relative;display:flex;flex-direction:column;max-height:calc(100vh - var(--ui-spacing-xl) * 2);background-color:var(--ui-bg);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-shadow-lg);animation:slideIn var(--ui-transition-normal)}.ui-modal--sm{max-width:400px}.ui-modal--md{max-width:560px}.ui-modal--lg{max-width:800px}.ui-modal--xl{max-width:1140px}.ui-modal--full{max-width:calc(100vw - var(--ui-spacing-xl) * 2);max-height:calc(100vh - var(--ui-spacing-xl) * 2)}.ui-modal__header{display:flex;align-items:center;justify-content:space-between;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-bottom:1px solid var(--ui-border)}.ui-modal__title{margin:0;font-size:var(--ui-font-lg);font-weight:600;color:var(--ui-text)}.ui-modal__close{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;margin:calc(var(--ui-spacing-sm) * -1);color:var(--ui-text-muted);background:transparent;border:none;border-radius:var(--ui-radius-sm);cursor:pointer;transition:all var(--ui-transition-fast)}.ui-modal__close:hover{color:var(--ui-text);background-color:var(--ui-bg-hover)}.ui-modal__close:focus-visible{outline:2px solid var(--ui-primary);outline-offset:2px}.ui-modal__body{flex:1;padding:var(--ui-spacing-lg);overflow-y:auto}.ui-modal__footer{display:flex;gap:var(--ui-spacing-sm);justify-content:flex-end;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-top:1px solid var(--ui-border)}.ui-modal__footer:empty{display:none}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-16px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
971
988
  }
972
989
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ModalComponent, decorators: [{
973
990
  type: Component,
974
- args: [{ selector: 'ui-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ui-modal__backdrop\" (click)=\"onBackdropClick($event)\">\n <div\n class=\"ui-modal__container\"\n [class]=\"containerClasses()\"\n [style.width]=\"width()\"\n [style.max-width]=\"maxWidth()\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n @if (title()) {\n <div class=\"ui-modal__header\">\n <h2 class=\"ui-modal__title\">{{ title() }}</h2>\n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"ui-modal__close\"\n aria-label=\"Close\"\n (click)=\"close()\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n </button>\n }\n </div>\n }\n\n <div class=\"ui-modal__body\">\n <ng-content />\n </div>\n\n <div class=\"ui-modal__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n </div>\n</div>\n", styles: [".ui-modal__backdrop{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:var(--ui-spacing-md);background-color:#00000080;animation:fadeIn var(--ui-transition-fast)}.ui-modal__container{position:relative;display:flex;flex-direction:column;max-height:calc(100vh - var(--ui-spacing-xl) * 2);background-color:var(--ui-bg);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-shadow-lg);animation:slideIn var(--ui-transition-normal)}.ui-modal--sm{max-width:400px}.ui-modal--md{max-width:560px}.ui-modal--lg{max-width:800px}.ui-modal--xl{max-width:1140px}.ui-modal--full{max-width:calc(100vw - var(--ui-spacing-xl) * 2);max-height:calc(100vh - var(--ui-spacing-xl) * 2)}.ui-modal__header{display:flex;align-items:center;justify-content:space-between;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-bottom:1px solid var(--ui-border)}.ui-modal__title{margin:0;font-size:var(--ui-font-lg);font-weight:600;color:var(--ui-text)}.ui-modal__close{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;margin:calc(var(--ui-spacing-sm) * -1);color:var(--ui-text-muted);background:transparent;border:none;border-radius:var(--ui-radius-sm);cursor:pointer;transition:all var(--ui-transition-fast)}.ui-modal__close:hover{color:var(--ui-text);background-color:var(--ui-bg-hover)}.ui-modal__close:focus-visible{outline:2px solid var(--ui-primary);outline-offset:2px}.ui-modal__body{flex:1;padding:var(--ui-spacing-lg);overflow-y:auto}.ui-modal__footer{display:flex;gap:var(--ui-spacing-sm);justify-content:flex-end;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-top:1px solid var(--ui-border)}.ui-modal__footer:empty{display:none}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-16px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
991
+ args: [{ selector: 'ui-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ui-modal__backdrop\" (mousedown)=\"onBackdropMouseDown($event)\" (click)=\"onBackdropClick($event)\">\n <div\n class=\"ui-modal__container\"\n [class]=\"containerClasses()\"\n [style.width]=\"width()\"\n [style.max-width]=\"maxWidth()\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n @if (title()) {\n <div class=\"ui-modal__header\">\n <h2 class=\"ui-modal__title\">{{ title() }}</h2>\n @if (showCloseButton()) {\n <button\n type=\"button\"\n class=\"ui-modal__close\"\n aria-label=\"Close\"\n (click)=\"close()\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n </button>\n }\n </div>\n }\n\n <div class=\"ui-modal__body\">\n <ng-content />\n </div>\n\n <div class=\"ui-modal__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n </div>\n</div>\n", styles: [".ui-modal__backdrop{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:var(--ui-spacing-md);background-color:#00000080;animation:fadeIn var(--ui-transition-fast)}.ui-modal__container{position:relative;display:flex;flex-direction:column;max-height:calc(100vh - var(--ui-spacing-xl) * 2);background-color:var(--ui-bg);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-shadow-lg);animation:slideIn var(--ui-transition-normal)}.ui-modal--sm{max-width:400px}.ui-modal--md{max-width:560px}.ui-modal--lg{max-width:800px}.ui-modal--xl{max-width:1140px}.ui-modal--full{max-width:calc(100vw - var(--ui-spacing-xl) * 2);max-height:calc(100vh - var(--ui-spacing-xl) * 2)}.ui-modal__header{display:flex;align-items:center;justify-content:space-between;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-bottom:1px solid var(--ui-border)}.ui-modal__title{margin:0;font-size:var(--ui-font-lg);font-weight:600;color:var(--ui-text)}.ui-modal__close{display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;margin:calc(var(--ui-spacing-sm) * -1);color:var(--ui-text-muted);background:transparent;border:none;border-radius:var(--ui-radius-sm);cursor:pointer;transition:all var(--ui-transition-fast)}.ui-modal__close:hover{color:var(--ui-text);background-color:var(--ui-bg-hover)}.ui-modal__close:focus-visible{outline:2px solid var(--ui-primary);outline-offset:2px}.ui-modal__body{flex:1;padding:var(--ui-spacing-lg);overflow-y:auto}.ui-modal__footer{display:flex;gap:var(--ui-spacing-sm);justify-content:flex-end;padding:var(--ui-spacing-md) var(--ui-spacing-lg);border-top:1px solid var(--ui-border)}.ui-modal__footer:empty{display:none}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideIn{0%{opacity:0;transform:translateY(-16px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
975
992
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], closeOnBackdropClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdropClick", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], onEscapePress: [{
976
993
  type: HostListener,
977
994
  args: ['document:keydown.escape']
@@ -1423,6 +1440,7 @@ class SelectComponent {
1423
1440
  asyncSearchAbortController = null;
1424
1441
  debounceTimer = null;
1425
1442
  elementRef = inject(ElementRef);
1443
+ document = inject(DOCUMENT);
1426
1444
  positionCleanup = null;
1427
1445
  initializedOptions = new WeakSet();
1428
1446
  constructor() {
@@ -1487,8 +1505,8 @@ class SelectComponent {
1487
1505
  }
1488
1506
  ngOnDestroy() {
1489
1507
  const dropdown = this.dropdownRef?.nativeElement;
1490
- if (dropdown?.parentElement === document.body) {
1491
- document.body.removeChild(dropdown);
1508
+ if (dropdown?.parentElement === this.document.body) {
1509
+ this.document.body.removeChild(dropdown);
1492
1510
  }
1493
1511
  this.removePositionListeners();
1494
1512
  this.cancelAsyncSearch();
@@ -2002,7 +2020,7 @@ class SelectComponent {
2002
2020
  if (!dropdown)
2003
2021
  return;
2004
2022
  dropdown.style.display = 'block';
2005
- document.body.appendChild(dropdown);
2023
+ this.document.body.appendChild(dropdown);
2006
2024
  this.updateDropdownPosition();
2007
2025
  this.addPositionListeners();
2008
2026
  }
@@ -2010,7 +2028,7 @@ class SelectComponent {
2010
2028
  const dropdown = this.dropdownRef?.nativeElement;
2011
2029
  if (!dropdown)
2012
2030
  return;
2013
- if (dropdown.parentElement === document.body) {
2031
+ if (dropdown.parentElement === this.document.body) {
2014
2032
  const wrapper = this.elementRef.nativeElement.querySelector('.ui-select-wrapper');
2015
2033
  if (wrapper) {
2016
2034
  wrapper.appendChild(dropdown);
@@ -2150,6 +2168,7 @@ class DropdownComponent {
2150
2168
  triggerRef;
2151
2169
  menuRef;
2152
2170
  elementRef = inject(ElementRef);
2171
+ document = inject(DOCUMENT);
2153
2172
  positionCleanup = null;
2154
2173
  contextMenuPosition = null;
2155
2174
  trigger = contentChild(DropdownTriggerDirective, ...(ngDevMode ? [{ debugName: "trigger" }] : []));
@@ -2185,8 +2204,8 @@ class DropdownComponent {
2185
2204
  }
2186
2205
  ngOnDestroy() {
2187
2206
  const menu = this.menuRef?.nativeElement;
2188
- if (menu?.parentElement === document.body) {
2189
- document.body.removeChild(menu);
2207
+ if (menu?.parentElement === this.document.body) {
2208
+ this.document.body.removeChild(menu);
2190
2209
  }
2191
2210
  this.removePositionListeners();
2192
2211
  }
@@ -2287,7 +2306,7 @@ class DropdownComponent {
2287
2306
  if (!menu)
2288
2307
  return;
2289
2308
  menu.style.display = 'block';
2290
- document.body.appendChild(menu);
2309
+ this.document.body.appendChild(menu);
2291
2310
  this.updateMenuPosition();
2292
2311
  this.addPositionListeners();
2293
2312
  }
@@ -2295,7 +2314,7 @@ class DropdownComponent {
2295
2314
  const menu = this.menuRef?.nativeElement;
2296
2315
  if (!menu)
2297
2316
  return;
2298
- if (menu.parentElement === document.body) {
2317
+ if (menu.parentElement === this.document.body) {
2299
2318
  const wrapper = this.elementRef.nativeElement.querySelector('.ui-dropdown');
2300
2319
  if (wrapper) {
2301
2320
  wrapper.appendChild(menu);
@@ -2675,6 +2694,8 @@ class TooltipDirective {
2675
2694
  tooltipPosition = input('top', ...(ngDevMode ? [{ debugName: "tooltipPosition" }] : []));
2676
2695
  tooltipDelay = input(200, ...(ngDevMode ? [{ debugName: "tooltipDelay" }] : []));
2677
2696
  tooltipDisabled = input(false, ...(ngDevMode ? [{ debugName: "tooltipDisabled" }] : []));
2697
+ document = inject(DOCUMENT);
2698
+ platformId = inject(PLATFORM_ID);
2678
2699
  tooltipElement = null;
2679
2700
  showTimeout = null;
2680
2701
  isVisible = signal(false, ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
@@ -2739,7 +2760,7 @@ class TooltipDirective {
2739
2760
  const arrow = this.renderer.createElement('span');
2740
2761
  this.renderer.addClass(arrow, 'ui-tooltip__arrow');
2741
2762
  this.renderer.appendChild(this.tooltipElement, arrow);
2742
- this.renderer.appendChild(document.body, this.tooltipElement);
2763
+ this.renderer.appendChild(this.document.body, this.tooltipElement);
2743
2764
  this.injectStyles();
2744
2765
  }
2745
2766
  positionTooltip() {
@@ -2778,13 +2799,13 @@ class TooltipDirective {
2778
2799
  }
2779
2800
  destroyTooltip() {
2780
2801
  if (this.tooltipElement) {
2781
- this.renderer.removeChild(document.body, this.tooltipElement);
2802
+ this.renderer.removeChild(this.document.body, this.tooltipElement);
2782
2803
  this.tooltipElement = null;
2783
2804
  }
2784
2805
  }
2785
2806
  injectStyles() {
2786
2807
  const styleId = 'ui-tooltip-styles';
2787
- if (document.getElementById(styleId))
2808
+ if (!isPlatformBrowser(this.platformId) || this.document.getElementById(styleId))
2788
2809
  return;
2789
2810
  const style = this.renderer.createElement('style');
2790
2811
  this.renderer.setProperty(style, 'id', styleId);
@@ -2847,7 +2868,7 @@ class TooltipDirective {
2847
2868
  margin-top: -4px;
2848
2869
  }
2849
2870
  `);
2850
- this.renderer.appendChild(document.head, style);
2871
+ this.renderer.appendChild(this.document.head, style);
2851
2872
  }
2852
2873
  ngOnDestroy() {
2853
2874
  this.hide();
@@ -4023,6 +4044,7 @@ class DatepickerComponent {
4023
4044
  focusedDate = signal(null, ...(ngDevMode ? [{ debugName: "focusedDate" }] : []));
4024
4045
  hoveredDate = signal(null, ...(ngDevMode ? [{ debugName: "hoveredDate" }] : []));
4025
4046
  elementRef = inject(ElementRef);
4047
+ document = inject(DOCUMENT);
4026
4048
  positionCleanup = null;
4027
4049
  static nextId = 0;
4028
4050
  generatedId = `ui-datepicker-${++DatepickerComponent.nextId}`;
@@ -4280,8 +4302,8 @@ class DatepickerComponent {
4280
4302
  }, ...(ngDevMode ? [{ debugName: "canNavigateNext" }] : []));
4281
4303
  ngOnDestroy() {
4282
4304
  const dropdown = this.dropdownRef?.nativeElement;
4283
- if (dropdown?.parentElement === document.body) {
4284
- document.body.removeChild(dropdown);
4305
+ if (dropdown?.parentElement === this.document.body) {
4306
+ this.document.body.removeChild(dropdown);
4285
4307
  }
4286
4308
  this.removePositionListeners();
4287
4309
  }
@@ -4597,7 +4619,7 @@ class DatepickerComponent {
4597
4619
  if (!dropdown)
4598
4620
  return;
4599
4621
  dropdown.style.display = 'block';
4600
- document.body.appendChild(dropdown);
4622
+ this.document.body.appendChild(dropdown);
4601
4623
  this.updateDropdownPosition();
4602
4624
  this.addPositionListeners();
4603
4625
  }
@@ -4605,7 +4627,7 @@ class DatepickerComponent {
4605
4627
  const dropdown = this.dropdownRef?.nativeElement;
4606
4628
  if (!dropdown)
4607
4629
  return;
4608
- if (dropdown.parentElement === document.body) {
4630
+ if (dropdown.parentElement === this.document.body) {
4609
4631
  const wrapper = this.elementRef.nativeElement.querySelector('.ui-datepicker-wrapper');
4610
4632
  if (wrapper) {
4611
4633
  wrapper.appendChild(dropdown);
@@ -4714,6 +4736,7 @@ class TimepickerComponent {
4714
4736
  selectedSecond = signal(0, ...(ngDevMode ? [{ debugName: "selectedSecond" }] : []));
4715
4737
  selectedPeriod = signal('AM', ...(ngDevMode ? [{ debugName: "selectedPeriod" }] : []));
4716
4738
  elementRef = inject(ElementRef);
4739
+ document = inject(DOCUMENT);
4717
4740
  positionCleanup = null;
4718
4741
  static nextId = 0;
4719
4742
  generatedId = `ui-timepicker-${++TimepickerComponent.nextId}`;
@@ -4779,8 +4802,8 @@ class TimepickerComponent {
4779
4802
  }, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
4780
4803
  ngOnDestroy() {
4781
4804
  const dropdown = this.dropdownRef?.nativeElement;
4782
- if (dropdown?.parentElement === document.body) {
4783
- document.body.removeChild(dropdown);
4805
+ if (dropdown?.parentElement === this.document.body) {
4806
+ this.document.body.removeChild(dropdown);
4784
4807
  }
4785
4808
  this.removePositionListeners();
4786
4809
  }
@@ -4942,7 +4965,7 @@ class TimepickerComponent {
4942
4965
  if (!dropdown)
4943
4966
  return;
4944
4967
  dropdown.style.display = 'block';
4945
- document.body.appendChild(dropdown);
4968
+ this.document.body.appendChild(dropdown);
4946
4969
  this.updateDropdownPosition();
4947
4970
  this.addPositionListeners();
4948
4971
  }
@@ -4950,7 +4973,7 @@ class TimepickerComponent {
4950
4973
  const dropdown = this.dropdownRef?.nativeElement;
4951
4974
  if (!dropdown)
4952
4975
  return;
4953
- if (dropdown.parentElement === document.body) {
4976
+ if (dropdown.parentElement === this.document.body) {
4954
4977
  const wrapper = this.elementRef.nativeElement.querySelector('.ui-timepicker-wrapper');
4955
4978
  if (wrapper) {
4956
4979
  wrapper.appendChild(dropdown);
@@ -5066,6 +5089,7 @@ class DatetimepickerComponent {
5066
5089
  selectedSecond = signal(0, ...(ngDevMode ? [{ debugName: "selectedSecond" }] : []));
5067
5090
  selectedPeriod = signal('AM', ...(ngDevMode ? [{ debugName: "selectedPeriod" }] : []));
5068
5091
  elementRef = inject(ElementRef);
5092
+ document = inject(DOCUMENT);
5069
5093
  positionCleanup = null;
5070
5094
  static nextId = 0;
5071
5095
  generatedId = `ui-datetimepicker-${++DatetimepickerComponent.nextId}`;
@@ -5274,8 +5298,8 @@ class DatetimepickerComponent {
5274
5298
  }, ...(ngDevMode ? [{ debugName: "canNavigateNext" }] : []));
5275
5299
  ngOnDestroy() {
5276
5300
  const dropdown = this.dropdownRef?.nativeElement;
5277
- if (dropdown?.parentElement === document.body) {
5278
- document.body.removeChild(dropdown);
5301
+ if (dropdown?.parentElement === this.document.body) {
5302
+ this.document.body.removeChild(dropdown);
5279
5303
  }
5280
5304
  this.removePositionListeners();
5281
5305
  }
@@ -5621,7 +5645,7 @@ class DatetimepickerComponent {
5621
5645
  if (!dropdown)
5622
5646
  return;
5623
5647
  dropdown.style.display = 'block';
5624
- document.body.appendChild(dropdown);
5648
+ this.document.body.appendChild(dropdown);
5625
5649
  this.updateDropdownPosition();
5626
5650
  this.addPositionListeners();
5627
5651
  }
@@ -5629,7 +5653,7 @@ class DatetimepickerComponent {
5629
5653
  const dropdown = this.dropdownRef?.nativeElement;
5630
5654
  if (!dropdown)
5631
5655
  return;
5632
- if (dropdown.parentElement === document.body) {
5656
+ if (dropdown.parentElement === this.document.body) {
5633
5657
  const wrapper = this.elementRef.nativeElement.querySelector('.ui-datetimepicker-wrapper');
5634
5658
  if (wrapper) {
5635
5659
  wrapper.appendChild(dropdown);
@@ -6267,6 +6291,8 @@ class TemplateInputComponent {
6267
6291
  inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : []));
6268
6292
  popoverRef;
6269
6293
  hostRef = inject(ElementRef);
6294
+ document = inject(DOCUMENT);
6295
+ platformId = inject(PLATFORM_ID);
6270
6296
  positionCleanup = null;
6271
6297
  currentSpanRect = null;
6272
6298
  isPortaled = false;
@@ -6461,7 +6487,9 @@ class TemplateInputComponent {
6461
6487
  `;
6462
6488
  injectStyles() {
6463
6489
  const styleId = 'ui-tmpl-styles';
6464
- let existing = document.getElementById(styleId);
6490
+ if (!isPlatformBrowser(this.platformId))
6491
+ return;
6492
+ let existing = this.document.getElementById(styleId);
6465
6493
  // Always replace to handle HMR / version upgrades
6466
6494
  if (existing) {
6467
6495
  existing.textContent = TemplateInputComponent.STYLE_CONTENT;
@@ -6470,11 +6498,11 @@ class TemplateInputComponent {
6470
6498
  const style = this.renderer.createElement('style');
6471
6499
  this.renderer.setProperty(style, 'id', styleId);
6472
6500
  this.renderer.setProperty(style, 'textContent', TemplateInputComponent.STYLE_CONTENT);
6473
- this.renderer.appendChild(document.head, style);
6501
+ this.renderer.appendChild(this.document.head, style);
6474
6502
  }
6475
6503
  portalPopover() {
6476
6504
  const el = this.popoverRef.nativeElement;
6477
- document.body.appendChild(el);
6505
+ this.document.body.appendChild(el);
6478
6506
  el.style.display = 'block';
6479
6507
  this.isPortaled = true;
6480
6508
  requestAnimationFrame(() => this.updatePopoverPosition());