@m1z23r/ngx-ui 1.1.37 → 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 +74 -27
- package/fesm2022/m1z23r-ngx-ui.mjs +49 -30
- package/fesm2022/m1z23r-ngx-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/m1z23r-ngx-ui.d.ts +13 -0
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
|
|
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
|
-
|
|
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` | `'
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
@@ -1432,6 +1440,7 @@ class SelectComponent {
|
|
|
1432
1440
|
asyncSearchAbortController = null;
|
|
1433
1441
|
debounceTimer = null;
|
|
1434
1442
|
elementRef = inject(ElementRef);
|
|
1443
|
+
document = inject(DOCUMENT);
|
|
1435
1444
|
positionCleanup = null;
|
|
1436
1445
|
initializedOptions = new WeakSet();
|
|
1437
1446
|
constructor() {
|
|
@@ -1496,8 +1505,8 @@ class SelectComponent {
|
|
|
1496
1505
|
}
|
|
1497
1506
|
ngOnDestroy() {
|
|
1498
1507
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
1499
|
-
if (dropdown?.parentElement === document.body) {
|
|
1500
|
-
document.body.removeChild(dropdown);
|
|
1508
|
+
if (dropdown?.parentElement === this.document.body) {
|
|
1509
|
+
this.document.body.removeChild(dropdown);
|
|
1501
1510
|
}
|
|
1502
1511
|
this.removePositionListeners();
|
|
1503
1512
|
this.cancelAsyncSearch();
|
|
@@ -2011,7 +2020,7 @@ class SelectComponent {
|
|
|
2011
2020
|
if (!dropdown)
|
|
2012
2021
|
return;
|
|
2013
2022
|
dropdown.style.display = 'block';
|
|
2014
|
-
document.body.appendChild(dropdown);
|
|
2023
|
+
this.document.body.appendChild(dropdown);
|
|
2015
2024
|
this.updateDropdownPosition();
|
|
2016
2025
|
this.addPositionListeners();
|
|
2017
2026
|
}
|
|
@@ -2019,7 +2028,7 @@ class SelectComponent {
|
|
|
2019
2028
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
2020
2029
|
if (!dropdown)
|
|
2021
2030
|
return;
|
|
2022
|
-
if (dropdown.parentElement === document.body) {
|
|
2031
|
+
if (dropdown.parentElement === this.document.body) {
|
|
2023
2032
|
const wrapper = this.elementRef.nativeElement.querySelector('.ui-select-wrapper');
|
|
2024
2033
|
if (wrapper) {
|
|
2025
2034
|
wrapper.appendChild(dropdown);
|
|
@@ -2159,6 +2168,7 @@ class DropdownComponent {
|
|
|
2159
2168
|
triggerRef;
|
|
2160
2169
|
menuRef;
|
|
2161
2170
|
elementRef = inject(ElementRef);
|
|
2171
|
+
document = inject(DOCUMENT);
|
|
2162
2172
|
positionCleanup = null;
|
|
2163
2173
|
contextMenuPosition = null;
|
|
2164
2174
|
trigger = contentChild(DropdownTriggerDirective, ...(ngDevMode ? [{ debugName: "trigger" }] : []));
|
|
@@ -2194,8 +2204,8 @@ class DropdownComponent {
|
|
|
2194
2204
|
}
|
|
2195
2205
|
ngOnDestroy() {
|
|
2196
2206
|
const menu = this.menuRef?.nativeElement;
|
|
2197
|
-
if (menu?.parentElement === document.body) {
|
|
2198
|
-
document.body.removeChild(menu);
|
|
2207
|
+
if (menu?.parentElement === this.document.body) {
|
|
2208
|
+
this.document.body.removeChild(menu);
|
|
2199
2209
|
}
|
|
2200
2210
|
this.removePositionListeners();
|
|
2201
2211
|
}
|
|
@@ -2296,7 +2306,7 @@ class DropdownComponent {
|
|
|
2296
2306
|
if (!menu)
|
|
2297
2307
|
return;
|
|
2298
2308
|
menu.style.display = 'block';
|
|
2299
|
-
document.body.appendChild(menu);
|
|
2309
|
+
this.document.body.appendChild(menu);
|
|
2300
2310
|
this.updateMenuPosition();
|
|
2301
2311
|
this.addPositionListeners();
|
|
2302
2312
|
}
|
|
@@ -2304,7 +2314,7 @@ class DropdownComponent {
|
|
|
2304
2314
|
const menu = this.menuRef?.nativeElement;
|
|
2305
2315
|
if (!menu)
|
|
2306
2316
|
return;
|
|
2307
|
-
if (menu.parentElement === document.body) {
|
|
2317
|
+
if (menu.parentElement === this.document.body) {
|
|
2308
2318
|
const wrapper = this.elementRef.nativeElement.querySelector('.ui-dropdown');
|
|
2309
2319
|
if (wrapper) {
|
|
2310
2320
|
wrapper.appendChild(menu);
|
|
@@ -2684,6 +2694,8 @@ class TooltipDirective {
|
|
|
2684
2694
|
tooltipPosition = input('top', ...(ngDevMode ? [{ debugName: "tooltipPosition" }] : []));
|
|
2685
2695
|
tooltipDelay = input(200, ...(ngDevMode ? [{ debugName: "tooltipDelay" }] : []));
|
|
2686
2696
|
tooltipDisabled = input(false, ...(ngDevMode ? [{ debugName: "tooltipDisabled" }] : []));
|
|
2697
|
+
document = inject(DOCUMENT);
|
|
2698
|
+
platformId = inject(PLATFORM_ID);
|
|
2687
2699
|
tooltipElement = null;
|
|
2688
2700
|
showTimeout = null;
|
|
2689
2701
|
isVisible = signal(false, ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
|
|
@@ -2748,7 +2760,7 @@ class TooltipDirective {
|
|
|
2748
2760
|
const arrow = this.renderer.createElement('span');
|
|
2749
2761
|
this.renderer.addClass(arrow, 'ui-tooltip__arrow');
|
|
2750
2762
|
this.renderer.appendChild(this.tooltipElement, arrow);
|
|
2751
|
-
this.renderer.appendChild(document.body, this.tooltipElement);
|
|
2763
|
+
this.renderer.appendChild(this.document.body, this.tooltipElement);
|
|
2752
2764
|
this.injectStyles();
|
|
2753
2765
|
}
|
|
2754
2766
|
positionTooltip() {
|
|
@@ -2787,13 +2799,13 @@ class TooltipDirective {
|
|
|
2787
2799
|
}
|
|
2788
2800
|
destroyTooltip() {
|
|
2789
2801
|
if (this.tooltipElement) {
|
|
2790
|
-
this.renderer.removeChild(document.body, this.tooltipElement);
|
|
2802
|
+
this.renderer.removeChild(this.document.body, this.tooltipElement);
|
|
2791
2803
|
this.tooltipElement = null;
|
|
2792
2804
|
}
|
|
2793
2805
|
}
|
|
2794
2806
|
injectStyles() {
|
|
2795
2807
|
const styleId = 'ui-tooltip-styles';
|
|
2796
|
-
if (document.getElementById(styleId))
|
|
2808
|
+
if (!isPlatformBrowser(this.platformId) || this.document.getElementById(styleId))
|
|
2797
2809
|
return;
|
|
2798
2810
|
const style = this.renderer.createElement('style');
|
|
2799
2811
|
this.renderer.setProperty(style, 'id', styleId);
|
|
@@ -2856,7 +2868,7 @@ class TooltipDirective {
|
|
|
2856
2868
|
margin-top: -4px;
|
|
2857
2869
|
}
|
|
2858
2870
|
`);
|
|
2859
|
-
this.renderer.appendChild(document.head, style);
|
|
2871
|
+
this.renderer.appendChild(this.document.head, style);
|
|
2860
2872
|
}
|
|
2861
2873
|
ngOnDestroy() {
|
|
2862
2874
|
this.hide();
|
|
@@ -4032,6 +4044,7 @@ class DatepickerComponent {
|
|
|
4032
4044
|
focusedDate = signal(null, ...(ngDevMode ? [{ debugName: "focusedDate" }] : []));
|
|
4033
4045
|
hoveredDate = signal(null, ...(ngDevMode ? [{ debugName: "hoveredDate" }] : []));
|
|
4034
4046
|
elementRef = inject(ElementRef);
|
|
4047
|
+
document = inject(DOCUMENT);
|
|
4035
4048
|
positionCleanup = null;
|
|
4036
4049
|
static nextId = 0;
|
|
4037
4050
|
generatedId = `ui-datepicker-${++DatepickerComponent.nextId}`;
|
|
@@ -4289,8 +4302,8 @@ class DatepickerComponent {
|
|
|
4289
4302
|
}, ...(ngDevMode ? [{ debugName: "canNavigateNext" }] : []));
|
|
4290
4303
|
ngOnDestroy() {
|
|
4291
4304
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
4292
|
-
if (dropdown?.parentElement === document.body) {
|
|
4293
|
-
document.body.removeChild(dropdown);
|
|
4305
|
+
if (dropdown?.parentElement === this.document.body) {
|
|
4306
|
+
this.document.body.removeChild(dropdown);
|
|
4294
4307
|
}
|
|
4295
4308
|
this.removePositionListeners();
|
|
4296
4309
|
}
|
|
@@ -4606,7 +4619,7 @@ class DatepickerComponent {
|
|
|
4606
4619
|
if (!dropdown)
|
|
4607
4620
|
return;
|
|
4608
4621
|
dropdown.style.display = 'block';
|
|
4609
|
-
document.body.appendChild(dropdown);
|
|
4622
|
+
this.document.body.appendChild(dropdown);
|
|
4610
4623
|
this.updateDropdownPosition();
|
|
4611
4624
|
this.addPositionListeners();
|
|
4612
4625
|
}
|
|
@@ -4614,7 +4627,7 @@ class DatepickerComponent {
|
|
|
4614
4627
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
4615
4628
|
if (!dropdown)
|
|
4616
4629
|
return;
|
|
4617
|
-
if (dropdown.parentElement === document.body) {
|
|
4630
|
+
if (dropdown.parentElement === this.document.body) {
|
|
4618
4631
|
const wrapper = this.elementRef.nativeElement.querySelector('.ui-datepicker-wrapper');
|
|
4619
4632
|
if (wrapper) {
|
|
4620
4633
|
wrapper.appendChild(dropdown);
|
|
@@ -4723,6 +4736,7 @@ class TimepickerComponent {
|
|
|
4723
4736
|
selectedSecond = signal(0, ...(ngDevMode ? [{ debugName: "selectedSecond" }] : []));
|
|
4724
4737
|
selectedPeriod = signal('AM', ...(ngDevMode ? [{ debugName: "selectedPeriod" }] : []));
|
|
4725
4738
|
elementRef = inject(ElementRef);
|
|
4739
|
+
document = inject(DOCUMENT);
|
|
4726
4740
|
positionCleanup = null;
|
|
4727
4741
|
static nextId = 0;
|
|
4728
4742
|
generatedId = `ui-timepicker-${++TimepickerComponent.nextId}`;
|
|
@@ -4788,8 +4802,8 @@ class TimepickerComponent {
|
|
|
4788
4802
|
}, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
|
|
4789
4803
|
ngOnDestroy() {
|
|
4790
4804
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
4791
|
-
if (dropdown?.parentElement === document.body) {
|
|
4792
|
-
document.body.removeChild(dropdown);
|
|
4805
|
+
if (dropdown?.parentElement === this.document.body) {
|
|
4806
|
+
this.document.body.removeChild(dropdown);
|
|
4793
4807
|
}
|
|
4794
4808
|
this.removePositionListeners();
|
|
4795
4809
|
}
|
|
@@ -4951,7 +4965,7 @@ class TimepickerComponent {
|
|
|
4951
4965
|
if (!dropdown)
|
|
4952
4966
|
return;
|
|
4953
4967
|
dropdown.style.display = 'block';
|
|
4954
|
-
document.body.appendChild(dropdown);
|
|
4968
|
+
this.document.body.appendChild(dropdown);
|
|
4955
4969
|
this.updateDropdownPosition();
|
|
4956
4970
|
this.addPositionListeners();
|
|
4957
4971
|
}
|
|
@@ -4959,7 +4973,7 @@ class TimepickerComponent {
|
|
|
4959
4973
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
4960
4974
|
if (!dropdown)
|
|
4961
4975
|
return;
|
|
4962
|
-
if (dropdown.parentElement === document.body) {
|
|
4976
|
+
if (dropdown.parentElement === this.document.body) {
|
|
4963
4977
|
const wrapper = this.elementRef.nativeElement.querySelector('.ui-timepicker-wrapper');
|
|
4964
4978
|
if (wrapper) {
|
|
4965
4979
|
wrapper.appendChild(dropdown);
|
|
@@ -5075,6 +5089,7 @@ class DatetimepickerComponent {
|
|
|
5075
5089
|
selectedSecond = signal(0, ...(ngDevMode ? [{ debugName: "selectedSecond" }] : []));
|
|
5076
5090
|
selectedPeriod = signal('AM', ...(ngDevMode ? [{ debugName: "selectedPeriod" }] : []));
|
|
5077
5091
|
elementRef = inject(ElementRef);
|
|
5092
|
+
document = inject(DOCUMENT);
|
|
5078
5093
|
positionCleanup = null;
|
|
5079
5094
|
static nextId = 0;
|
|
5080
5095
|
generatedId = `ui-datetimepicker-${++DatetimepickerComponent.nextId}`;
|
|
@@ -5283,8 +5298,8 @@ class DatetimepickerComponent {
|
|
|
5283
5298
|
}, ...(ngDevMode ? [{ debugName: "canNavigateNext" }] : []));
|
|
5284
5299
|
ngOnDestroy() {
|
|
5285
5300
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
5286
|
-
if (dropdown?.parentElement === document.body) {
|
|
5287
|
-
document.body.removeChild(dropdown);
|
|
5301
|
+
if (dropdown?.parentElement === this.document.body) {
|
|
5302
|
+
this.document.body.removeChild(dropdown);
|
|
5288
5303
|
}
|
|
5289
5304
|
this.removePositionListeners();
|
|
5290
5305
|
}
|
|
@@ -5630,7 +5645,7 @@ class DatetimepickerComponent {
|
|
|
5630
5645
|
if (!dropdown)
|
|
5631
5646
|
return;
|
|
5632
5647
|
dropdown.style.display = 'block';
|
|
5633
|
-
document.body.appendChild(dropdown);
|
|
5648
|
+
this.document.body.appendChild(dropdown);
|
|
5634
5649
|
this.updateDropdownPosition();
|
|
5635
5650
|
this.addPositionListeners();
|
|
5636
5651
|
}
|
|
@@ -5638,7 +5653,7 @@ class DatetimepickerComponent {
|
|
|
5638
5653
|
const dropdown = this.dropdownRef?.nativeElement;
|
|
5639
5654
|
if (!dropdown)
|
|
5640
5655
|
return;
|
|
5641
|
-
if (dropdown.parentElement === document.body) {
|
|
5656
|
+
if (dropdown.parentElement === this.document.body) {
|
|
5642
5657
|
const wrapper = this.elementRef.nativeElement.querySelector('.ui-datetimepicker-wrapper');
|
|
5643
5658
|
if (wrapper) {
|
|
5644
5659
|
wrapper.appendChild(dropdown);
|
|
@@ -6276,6 +6291,8 @@ class TemplateInputComponent {
|
|
|
6276
6291
|
inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : []));
|
|
6277
6292
|
popoverRef;
|
|
6278
6293
|
hostRef = inject(ElementRef);
|
|
6294
|
+
document = inject(DOCUMENT);
|
|
6295
|
+
platformId = inject(PLATFORM_ID);
|
|
6279
6296
|
positionCleanup = null;
|
|
6280
6297
|
currentSpanRect = null;
|
|
6281
6298
|
isPortaled = false;
|
|
@@ -6470,7 +6487,9 @@ class TemplateInputComponent {
|
|
|
6470
6487
|
`;
|
|
6471
6488
|
injectStyles() {
|
|
6472
6489
|
const styleId = 'ui-tmpl-styles';
|
|
6473
|
-
|
|
6490
|
+
if (!isPlatformBrowser(this.platformId))
|
|
6491
|
+
return;
|
|
6492
|
+
let existing = this.document.getElementById(styleId);
|
|
6474
6493
|
// Always replace to handle HMR / version upgrades
|
|
6475
6494
|
if (existing) {
|
|
6476
6495
|
existing.textContent = TemplateInputComponent.STYLE_CONTENT;
|
|
@@ -6479,11 +6498,11 @@ class TemplateInputComponent {
|
|
|
6479
6498
|
const style = this.renderer.createElement('style');
|
|
6480
6499
|
this.renderer.setProperty(style, 'id', styleId);
|
|
6481
6500
|
this.renderer.setProperty(style, 'textContent', TemplateInputComponent.STYLE_CONTENT);
|
|
6482
|
-
this.renderer.appendChild(document.head, style);
|
|
6501
|
+
this.renderer.appendChild(this.document.head, style);
|
|
6483
6502
|
}
|
|
6484
6503
|
portalPopover() {
|
|
6485
6504
|
const el = this.popoverRef.nativeElement;
|
|
6486
|
-
document.body.appendChild(el);
|
|
6505
|
+
this.document.body.appendChild(el);
|
|
6487
6506
|
el.style.display = 'block';
|
|
6488
6507
|
this.isPortaled = true;
|
|
6489
6508
|
requestAnimationFrame(() => this.updatePopoverPosition());
|