@taiga-ui/core 5.25.0 → 5.26.0-canary.eb5f53f
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/classes/accessors.d.ts +3 -0
- package/components/scrollbar/scrollbar.component.d.ts +2 -2
- package/fesm2022/taiga-ui-core-classes.mjs +1 -0
- package/fesm2022/taiga-ui-core-classes.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-button.mjs +2 -2
- package/fesm2022/taiga-ui-core-components-button.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-cell.mjs +3 -3
- package/fesm2022/taiga-ui-core-components-cell.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-checkbox.mjs +2 -2
- package/fesm2022/taiga-ui-core-components-checkbox.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-data-list.mjs +4 -4
- package/fesm2022/taiga-ui-core-components-data-list.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-icon.mjs +2 -2
- package/fesm2022/taiga-ui-core-components-icon.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-label.mjs +3 -3
- package/fesm2022/taiga-ui-core-components-label.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-link.mjs +2 -2
- package/fesm2022/taiga-ui-core-components-link.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-notification.mjs +2 -2
- package/fesm2022/taiga-ui-core-components-notification.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-radio.mjs +2 -2
- package/fesm2022/taiga-ui-core-components-radio.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-root.mjs +1 -1
- package/fesm2022/taiga-ui-core-components-root.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-scrollbar.mjs +13 -12
- package/fesm2022/taiga-ui-core-components-scrollbar.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-textfield.mjs +4 -4
- package/fesm2022/taiga-ui-core-components-textfield.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-title.mjs +3 -3
- package/fesm2022/taiga-ui-core-components-title.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-directives-appearance.mjs +3 -3
- package/fesm2022/taiga-ui-core-directives-appearance.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-directives-group.mjs +3 -3
- package/fesm2022/taiga-ui-core-directives-group.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-directives-icons.mjs +3 -3
- package/fesm2022/taiga-ui-core-directives-icons.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-portals-alert.mjs +3 -3
- package/fesm2022/taiga-ui-core-portals-alert.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-portals-dialog.mjs +2 -2
- package/fesm2022/taiga-ui-core-portals-dialog.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-portals-dropdown.mjs +270 -163
- package/fesm2022/taiga-ui-core-portals-dropdown.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-portals-hint.mjs +7 -21
- package/fesm2022/taiga-ui-core-portals-hint.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-portals-modal.mjs +3 -3
- package/fesm2022/taiga-ui-core-portals-modal.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-tokens.mjs +1 -1
- package/fesm2022/taiga-ui-core-tokens.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-utils-dom.mjs +21 -1
- package/fesm2022/taiga-ui-core-utils-dom.mjs.map +1 -1
- package/package.json +19 -19
- package/portals/dropdown/dropdown-anchored.directive.d.ts +4 -1
- package/portals/dropdown/dropdown-context.directive.d.ts +3 -4
- package/portals/dropdown/dropdown-position-sided.directive.d.ts +2 -0
- package/portals/dropdown/dropdown-position.directive.d.ts +2 -0
- package/portals/dropdown/dropdown-selection.directive.d.ts +1 -1
- package/portals/dropdown/dropdown.component.d.ts +10 -8
- package/portals/dropdown/dropdown.providers.d.ts +2 -3
- package/portals/hint/hint-pointer.directive.d.ts +1 -3
- package/utils/dom/anchor-delegate.d.ts +1 -0
- package/utils/dom/index.d.ts +1 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { tuiProvide, tuiDirectiveBinding, tuiCreateOptions } from '@taiga-ui/cdk/utils/di';
|
|
2
2
|
import { coerceArray } from '@angular/cdk/coercion';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import {
|
|
4
|
+
import { InjectionToken, Optional, Self, SkipSelf, inject, Directive, computed, ChangeDetectionStrategy, Component, Injectable, input, effect, ElementRef, INJECTOR, ChangeDetectorRef, signal, TemplateRef, contentChild, model, PLATFORM_ID, ViewContainerRef } from '@angular/core';
|
|
5
5
|
import { takeUntilDestroyed, outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
|
|
6
6
|
import { tuiZonefreeScheduler, tuiIfMap, tuiCloseWatcher, tuiTypedFromEvent, tuiStopPropagation, tuiZoneOptimized } from '@taiga-ui/cdk/observables';
|
|
7
7
|
import { tuiInjectElement, tuiGetActualTarget, tuiIsElement, tuiIsElementEditable, tuiIsHTMLElement, tuiPointToClientRect, tuiIsTextNode, tuiIsTextfield } from '@taiga-ui/cdk/utils/dom';
|
|
8
|
-
import {
|
|
8
|
+
import { TuiRectAccessor, TuiPositionAccessor, tuiProvideAccessor, tuiInjectAccessor, tuiAsPositionAccessor, TuiDriverDirective, tuiAsRectAccessor, tuiAsVehicle, tuiAsDriver, TuiDriver } from '@taiga-ui/core/classes';
|
|
9
9
|
import { TuiPopupService } from '@taiga-ui/core/portals/popup';
|
|
10
|
-
import { tuiCheckFixedPosition, tuiGetWordRange } from '@taiga-ui/core/utils/dom';
|
|
10
|
+
import { tuiCheckFixedPosition, tuiAnchorDelegate, tuiGetWordRange } from '@taiga-ui/core/utils/dom';
|
|
11
11
|
import { PolymorpheusOutlet, PolymorpheusComponent, PolymorpheusTemplate } from '@taiga-ui/polymorpheus';
|
|
12
|
-
import {
|
|
12
|
+
import { takeWhile, map, Subject, distinctUntilChanged, BehaviorSubject, throttleTime, merge, filter, EMPTY, switchMap, delay, startWith, takeUntil, fromEvent, of, tap, share, combineLatest } from 'rxjs';
|
|
13
13
|
import * as i1 from '@taiga-ui/cdk/directives/active-zone';
|
|
14
14
|
import { TuiActiveZone } from '@taiga-ui/cdk/directives/active-zone';
|
|
15
15
|
import * as i2 from '@taiga-ui/cdk/directives/animated';
|
|
16
16
|
import { TuiAnimated } from '@taiga-ui/cdk/directives/animated';
|
|
17
|
-
import { TuiScrollbar } from '@taiga-ui/core/components/scrollbar';
|
|
18
|
-
import { TUI_VIEWPORT, TUI_DARK_MODE, TUI_SELECTION_STREAM } from '@taiga-ui/core/tokens';
|
|
17
|
+
import { TuiScrollbar, TuiScrollControls, TUI_SCROLL_REF } from '@taiga-ui/core/components/scrollbar';
|
|
18
|
+
import { TUI_VIEWPORT, TUI_ANCHOR_SUPPORT, TUI_DARK_MODE, TUI_SELECTION_STREAM } from '@taiga-ui/core/tokens';
|
|
19
19
|
import { EMPTY_CLIENT_RECT, TUI_TRUE_HANDLER, CHAR_ZERO_WIDTH_SPACE, CHAR_NO_BREAK_SPACE } from '@taiga-ui/cdk/constants';
|
|
20
20
|
import { tuiClamp } from '@taiga-ui/cdk/utils/math';
|
|
21
21
|
import { tuiPx, tuiGenerateId, tuiSetSignal, tuiIsString } from '@taiga-ui/cdk/utils/miscellaneous';
|
|
@@ -27,28 +27,12 @@ import { TuiObscured } from '@taiga-ui/cdk/directives/obscured';
|
|
|
27
27
|
import { tuiIsFocusable, tuiGetClosestFocusable, tuiIsFocusedIn, tuiGetFocused } from '@taiga-ui/cdk/utils/focus';
|
|
28
28
|
import { WA_IS_TOUCH } from '@ng-web-apis/platform';
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriver }); }
|
|
37
|
-
}
|
|
38
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriver, decorators: [{
|
|
39
|
-
type: Injectable
|
|
40
|
-
}], ctorParameters: () => [] });
|
|
41
|
-
class TuiDropdownDriverDirective extends TuiDriverDirective {
|
|
42
|
-
constructor() {
|
|
43
|
-
super(...arguments);
|
|
44
|
-
this.type = 'dropdown';
|
|
45
|
-
}
|
|
46
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriverDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
47
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownDriverDirective, isStandalone: true, usesInheritance: true, ngImport: i0 }); }
|
|
48
|
-
}
|
|
49
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriverDirective, decorators: [{
|
|
50
|
-
type: Directive
|
|
51
|
-
}] });
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated: remove in v6
|
|
32
|
+
*/
|
|
33
|
+
const TUI_DROPDOWN_CONTEXT = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_CONTEXT' : '');
|
|
34
|
+
const TUI_DROPDOWN_HOST = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_HOST' : '');
|
|
35
|
+
const TUI_DROPDOWN_ANCHOR = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_ANCHOR' : '');
|
|
52
36
|
|
|
53
37
|
const TUI_DROPDOWN_DEFAULT_OPTIONS = {
|
|
54
38
|
align: 'start',
|
|
@@ -104,25 +88,45 @@ class TuiDropdownAnchored {
|
|
|
104
88
|
constructor() {
|
|
105
89
|
this.el = tuiInjectElement();
|
|
106
90
|
this.directive = inject(TuiDropdownDirective);
|
|
107
|
-
this.
|
|
91
|
+
this.rect = inject(TuiRectAccessor);
|
|
108
92
|
this.viewport = inject(TUI_VIEWPORT);
|
|
109
93
|
this.vvs = inject(TuiVisualViewportService);
|
|
110
94
|
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
111
95
|
this.position = this.directive.position;
|
|
96
|
+
this.accessor = inject(TuiPositionAccessor);
|
|
112
97
|
this.styles$ = inject(TuiPositionService).pipe(takeWhile(() => this.directive.el.isConnected &&
|
|
113
98
|
this.directive.el.getClientRects().length > 0), map((v) => (this.position === 'fixed' ? this.vvs.correct(v) : v)), map((point) => this.getStyles(...point)), takeUntilDestroyed());
|
|
99
|
+
this.anchored = inject(TUI_ANCHOR_SUPPORT) &&
|
|
100
|
+
'position' in this.accessor &&
|
|
101
|
+
this.viewport.type === 'window';
|
|
114
102
|
}
|
|
115
103
|
ngAfterViewInit() {
|
|
116
|
-
this.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
if (this.anchored) {
|
|
105
|
+
this.accessor.position?.(this.el);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.styles$.subscribe({
|
|
109
|
+
next: (styles) => Object.assign(this.el.style, styles),
|
|
110
|
+
complete: () => this.directive.toggle(false),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// https://github.com/w3c/csswg-drafts/issues/14112
|
|
115
|
+
retrigger() {
|
|
116
|
+
if (!this.anchored ||
|
|
117
|
+
this.el.scrollHeight === this.el.clientHeight ||
|
|
118
|
+
this.el.clientHeight === this.options.maxHeight) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
this.el.style.position = 'static';
|
|
122
|
+
void this.el.offsetHeight;
|
|
123
|
+
this.el.style.position = 'fixed';
|
|
120
124
|
}
|
|
121
125
|
getStyles(x, y) {
|
|
122
126
|
const { maxHeight, minHeight, offset, limitWidth } = this.options;
|
|
123
127
|
const parent = this.el.offsetParent?.getBoundingClientRect() || EMPTY_CLIENT_RECT;
|
|
124
128
|
const { left = 0, top = 0 } = this.position === 'fixed' ? {} : parent;
|
|
125
|
-
const rect = this.
|
|
129
|
+
const rect = this.rect.getClientRect();
|
|
126
130
|
const viewport = this.viewport.getClientRect();
|
|
127
131
|
const zoom = this.directive.el.currentCSSZoom || 1;
|
|
128
132
|
const above = rect.top - viewport.top - 2 * offset;
|
|
@@ -144,7 +148,7 @@ class TuiDropdownAnchored {
|
|
|
144
148
|
};
|
|
145
149
|
}
|
|
146
150
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownAnchored, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
147
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownAnchored, isStandalone: true, providers: [
|
|
151
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownAnchored, isStandalone: true, host: { listeners: { "window:scrollend.zoneless.capture": "retrigger()" }, properties: { "class._anchored": "anchored" } }, providers: [
|
|
148
152
|
TuiPositionService,
|
|
149
153
|
tuiProvideAccessor(TuiPositionAccessor, 'dropdown'),
|
|
150
154
|
tuiProvideAccessor(TuiRectAccessor, 'dropdown'),
|
|
@@ -158,41 +162,224 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
158
162
|
tuiProvideAccessor(TuiPositionAccessor, 'dropdown'),
|
|
159
163
|
tuiProvideAccessor(TuiRectAccessor, 'dropdown'),
|
|
160
164
|
],
|
|
165
|
+
host: {
|
|
166
|
+
'[class._anchored]': 'anchored',
|
|
167
|
+
'(window:scrollend.zoneless.capture)': 'retrigger()',
|
|
168
|
+
},
|
|
161
169
|
}]
|
|
162
170
|
}] });
|
|
163
171
|
|
|
172
|
+
class TuiDropdownPosition extends TuiPositionAccessor {
|
|
173
|
+
constructor() {
|
|
174
|
+
super(...arguments);
|
|
175
|
+
this.el = tuiInjectElement();
|
|
176
|
+
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
177
|
+
this.viewport = inject(TUI_VIEWPORT);
|
|
178
|
+
this.anchor = inject(TUI_DROPDOWN_ANCHOR);
|
|
179
|
+
this.direction = new Subject();
|
|
180
|
+
this.type = 'dropdown';
|
|
181
|
+
this.accessor = tuiInjectAccessor(TuiRectAccessor, 'dropdown');
|
|
182
|
+
this.tuiDropdownDirectionChange = outputFromObservable(this.direction.pipe(distinctUntilChanged()));
|
|
183
|
+
}
|
|
184
|
+
position(element) {
|
|
185
|
+
const { direction, align, offset, limitWidth, minHeight, maxHeight } = this.options;
|
|
186
|
+
const rect = this.anchor.nativeElement.getBoundingClientRect();
|
|
187
|
+
const viewport = this.viewport.getClientRect();
|
|
188
|
+
const horizontal = align === 'center' ? '' : `span-x-${invert(align)}`;
|
|
189
|
+
const height = Math.min(element.clientHeight, maxHeight) + offset * 2;
|
|
190
|
+
const vertical = direction || 'bottom';
|
|
191
|
+
const top = rect.top - viewport.top;
|
|
192
|
+
const bottom = viewport.bottom - rect.bottom;
|
|
193
|
+
const available = vertical === 'top' ? top : bottom;
|
|
194
|
+
const max = Math.max(top, bottom);
|
|
195
|
+
Object.assign(element.style, {
|
|
196
|
+
position: 'fixed',
|
|
197
|
+
visibility: 'visible',
|
|
198
|
+
positionAnchor: this.anchor.nativeElement.dataset.tuiAnchor,
|
|
199
|
+
positionArea: `${available < height && max !== available ? flip(vertical) : vertical} ${horizontal}`,
|
|
200
|
+
marginBlock: `${offset}px`,
|
|
201
|
+
minBlockSize: `calc-size(fit-content, min(size, ${minHeight}px))`,
|
|
202
|
+
maxBlockSize: `calc-size(fit-content, min(size, ${maxHeight}px))`,
|
|
203
|
+
minInlineSize: limitWidth === 'min' ? 'anchor-size(inline)' : '',
|
|
204
|
+
inlineSize: limitWidth === 'fixed' ? 'anchor-size(inline)' : '',
|
|
205
|
+
blockSize: `calc-size(fit-content, calc(100% - ${2 * offset}px))`,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
getPosition({ width, height }) {
|
|
209
|
+
if (!width && !height) {
|
|
210
|
+
this.previous = undefined;
|
|
211
|
+
}
|
|
212
|
+
const hostRect = this.accessor.getClientRect();
|
|
213
|
+
const viewportRect = this.viewport.getClientRect();
|
|
214
|
+
const { minHeight, direction, offset, limitWidth } = this.options;
|
|
215
|
+
const align = this.getAlign(this.options.align);
|
|
216
|
+
const previous = this.previous || direction || 'bottom';
|
|
217
|
+
const viewport = {
|
|
218
|
+
top: viewportRect.top - offset,
|
|
219
|
+
bottom: viewportRect.bottom + offset,
|
|
220
|
+
right: viewportRect.right - offset,
|
|
221
|
+
left: viewportRect.left + offset,
|
|
222
|
+
};
|
|
223
|
+
const available = {
|
|
224
|
+
top: hostRect.top - 2 * offset - viewport.top,
|
|
225
|
+
bottom: viewport.bottom - hostRect.bottom - 2 * offset,
|
|
226
|
+
};
|
|
227
|
+
const rectWidth = limitWidth === 'fixed' ? hostRect.width : width;
|
|
228
|
+
const right = Math.max(hostRect.right - rectWidth, offset);
|
|
229
|
+
const left = hostRect.left + width < viewport.right ? hostRect.left : right;
|
|
230
|
+
const better = available.top > available.bottom ? 'top' : 'bottom';
|
|
231
|
+
const position = {
|
|
232
|
+
top: hostRect.top - offset - height,
|
|
233
|
+
bottom: hostRect.bottom + offset,
|
|
234
|
+
right: Math.max(viewport.left, right),
|
|
235
|
+
center: hostRect.left + hostRect.width / 2 + width / 2 < viewport.right
|
|
236
|
+
? hostRect.left + hostRect.width / 2 - width / 2
|
|
237
|
+
: right,
|
|
238
|
+
left: Math.max(viewport.left, left),
|
|
239
|
+
};
|
|
240
|
+
if ((available[previous] > minHeight && direction) ||
|
|
241
|
+
available[previous] > height) {
|
|
242
|
+
this.direction.next(previous);
|
|
243
|
+
return [position[align], position[previous]];
|
|
244
|
+
}
|
|
245
|
+
this.previous = better;
|
|
246
|
+
this.direction.next(better);
|
|
247
|
+
return [position[align], position[better]];
|
|
248
|
+
}
|
|
249
|
+
getAlign(align) {
|
|
250
|
+
const rtl = this.el.matches('[dir="rtl"] :scope');
|
|
251
|
+
if (rtl && align === 'start') {
|
|
252
|
+
return 'right';
|
|
253
|
+
}
|
|
254
|
+
if (rtl && align === 'end') {
|
|
255
|
+
return 'left';
|
|
256
|
+
}
|
|
257
|
+
if (align === 'center') {
|
|
258
|
+
return 'center';
|
|
259
|
+
}
|
|
260
|
+
return align === 'end' ? 'right' : 'left';
|
|
261
|
+
}
|
|
262
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
263
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownPosition, isStandalone: true, outputs: { tuiDropdownDirectionChange: "tuiDropdownDirectionChange" }, providers: [tuiAsPositionAccessor(TuiDropdownPosition)], usesInheritance: true, ngImport: i0 }); }
|
|
264
|
+
}
|
|
265
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, decorators: [{
|
|
266
|
+
type: Directive,
|
|
267
|
+
args: [{ providers: [tuiAsPositionAccessor(TuiDropdownPosition)] }]
|
|
268
|
+
}] });
|
|
269
|
+
// TODO: Review in v6 to possible sync alignment with native anchors
|
|
270
|
+
function invert(align) {
|
|
271
|
+
return align === 'start' ? 'end' : 'start';
|
|
272
|
+
}
|
|
273
|
+
function flip(direction) {
|
|
274
|
+
return direction === 'top' ? 'bottom' : 'top';
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const TUI_DROPDOWN_COMPONENT = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_COMPONENT' : '', { factory: () => TuiDropdownComponent });
|
|
164
278
|
/**
|
|
165
|
-
*
|
|
166
|
-
* This component is used to show template in a portal
|
|
167
|
-
* using default style of white rounded box with a shadow
|
|
279
|
+
* TODO: Remove extends TuiScrollbar in v6 when TuiScrollable is dropped
|
|
168
280
|
*/
|
|
169
|
-
class TuiDropdownComponent {
|
|
281
|
+
class TuiDropdownComponent extends TuiScrollbar {
|
|
170
282
|
constructor() {
|
|
283
|
+
super(...arguments);
|
|
284
|
+
this.anchor = inject(TUI_DROPDOWN_ANCHOR);
|
|
285
|
+
this.position = inject(TuiDropdownPosition);
|
|
286
|
+
this.darkMode = inject(TUI_DARK_MODE);
|
|
171
287
|
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
172
288
|
this.directive = inject(TuiDropdownDirective);
|
|
173
|
-
this.context = inject(TUI_DROPDOWN_CONTEXT, { optional: true });
|
|
174
|
-
this.darkMode = inject(TUI_DARK_MODE);
|
|
175
289
|
this.theme = computed((_ = this.darkMode()) => this.directive.el.closest('[tuiTheme]')?.getAttribute('tuiTheme'));
|
|
176
290
|
this.close = () => this.directive.toggle(false);
|
|
177
291
|
}
|
|
178
|
-
|
|
179
|
-
|
|
292
|
+
ngOnDestroy() {
|
|
293
|
+
if (!this.anchor.nativeElement.isConnected) {
|
|
294
|
+
this.el.style.setProperty('visibility', 'hidden');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
onResize({ target, contentRect }) {
|
|
298
|
+
if (!target.checkVisibility({ opacityProperty: true })) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (contentRect.width) {
|
|
302
|
+
this.position.direction.next(contentRect.height ? 'bottom' : 'top');
|
|
303
|
+
this.el.style.setProperty('visibility', 'visible');
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
this.el.style.setProperty('visibility', 'hidden');
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
310
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownComponent, isStandalone: true, selector: "tui-dropdown", host: { properties: { "attr.data-appearance": "options.appearance", "attr.tuiTheme": "theme()", "style.max-block-size.px": "options.maxHeight" } }, providers: [
|
|
311
|
+
{
|
|
312
|
+
provide: TUI_SCROLL_REF,
|
|
313
|
+
useFactory: () => inject(TuiDropdownComponent).browserScrollRef,
|
|
314
|
+
},
|
|
315
|
+
], usesInheritance: true, hostDirectives: [{ directive: i1.TuiActiveZone }, { directive: i2.TuiAnimated }, { directive: TuiDropdownAnchored }], ngImport: i0, template: `
|
|
316
|
+
<tui-scroll-controls class="t-scrollbar" />
|
|
317
|
+
<div class="t-wrapper">
|
|
318
|
+
<div
|
|
319
|
+
*polymorpheusOutlet="
|
|
320
|
+
directive.content() as text;
|
|
321
|
+
context: {$implicit: close}
|
|
322
|
+
"
|
|
323
|
+
[innerHTML]="text"
|
|
324
|
+
></div>
|
|
325
|
+
</div>
|
|
326
|
+
<div
|
|
327
|
+
class="t-detector"
|
|
328
|
+
(resize)="onResize($any($event)[0])"
|
|
329
|
+
></div>
|
|
330
|
+
`, isInline: true, styles: [":host{position:absolute;display:flex;box-shadow:var(--tui-shadow-medium);color:var(--tui-text-primary);background:var(--tui-background-elevation-1);border-radius:var(--tui-radius-m);overflow:auto;isolation:isolate;pointer-events:auto;outline-offset:-1px;outline:1px solid color-mix(in srgb,rgb(from var(--tui-border-normal) r g b / 1) 12%,var(--tui-background-elevation-1));overscroll-behavior:none;position-visibility:anchors-valid;position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline;--tui-from: translateY(-1rem)}:host:has(tui-data-list[data-size=l]){border-radius:var(--tui-radius-l)}:host.tui-enter,:host.tui-leave{animation-name:tuiFade,tuiSlide;animation-duration:calc(var(--tui-duration) / 2);pointer-events:none}:host:not([style*=top]){visibility:hidden}:host._delegated{scroll-timeline:none}:host:not(._anchored) .t-detector{display:none}.t-wrapper{z-index:-1;flex:1}.t-wrapper>*{padding:1rem}.t-detector{position:inherit;inset:anchor(top) 1rem calc(anchor(--t-scrollbar top) - 1rem);pointer-events:none;inline-size:calc(anchor-size(inline,-1px) + 1px);position-anchor:inherit;position-visibility:always}@supports (anchor-name: --t-scrollbar){.t-scrollbar{position:fixed;inset:anchor(top) anchor(right) anchor(bottom) anchor(left);position-anchor:--t-scrollbar;min-inline-size:0;min-block-size:0;margin:0}}\n"], dependencies: [{ kind: "directive", type: PolymorpheusOutlet, selector: "[polymorpheusOutlet]", inputs: ["polymorpheusOutlet", "polymorpheusOutletContext"] }, { kind: "component", type: TuiScrollControls, selector: "tui-scroll-controls" }], changeDetection: i0.ChangeDetectionStrategy.Default }); }
|
|
180
331
|
}
|
|
181
332
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownComponent, decorators: [{
|
|
182
333
|
type: Component,
|
|
183
|
-
args: [{ selector: 'tui-dropdown', imports: [PolymorpheusOutlet,
|
|
334
|
+
args: [{ selector: 'tui-dropdown', imports: [PolymorpheusOutlet, TuiScrollControls], template: `
|
|
335
|
+
<tui-scroll-controls class="t-scrollbar" />
|
|
336
|
+
<div class="t-wrapper">
|
|
337
|
+
<div
|
|
338
|
+
*polymorpheusOutlet="
|
|
339
|
+
directive.content() as text;
|
|
340
|
+
context: {$implicit: close}
|
|
341
|
+
"
|
|
342
|
+
[innerHTML]="text"
|
|
343
|
+
></div>
|
|
344
|
+
</div>
|
|
345
|
+
<div
|
|
346
|
+
class="t-detector"
|
|
347
|
+
(resize)="onResize($any($event)[0])"
|
|
348
|
+
></div>
|
|
349
|
+
`, changeDetection: ChangeDetectionStrategy.Default, providers: [
|
|
350
|
+
{
|
|
351
|
+
provide: TUI_SCROLL_REF,
|
|
352
|
+
useFactory: () => inject(TuiDropdownComponent).browserScrollRef,
|
|
353
|
+
},
|
|
354
|
+
], hostDirectives: [TuiActiveZone, TuiAnimated, TuiDropdownAnchored], host: {
|
|
184
355
|
'[attr.data-appearance]': 'options.appearance',
|
|
185
356
|
'[attr.tuiTheme]': 'theme()',
|
|
186
|
-
|
|
357
|
+
'[style.max-block-size.px]': 'options.maxHeight',
|
|
358
|
+
}, styles: [":host{position:absolute;display:flex;box-shadow:var(--tui-shadow-medium);color:var(--tui-text-primary);background:var(--tui-background-elevation-1);border-radius:var(--tui-radius-m);overflow:auto;isolation:isolate;pointer-events:auto;outline-offset:-1px;outline:1px solid color-mix(in srgb,rgb(from var(--tui-border-normal) r g b / 1) 12%,var(--tui-background-elevation-1));overscroll-behavior:none;position-visibility:anchors-valid;position-try-fallbacks:flip-block,flip-inline,flip-block flip-inline;--tui-from: translateY(-1rem)}:host:has(tui-data-list[data-size=l]){border-radius:var(--tui-radius-l)}:host.tui-enter,:host.tui-leave{animation-name:tuiFade,tuiSlide;animation-duration:calc(var(--tui-duration) / 2);pointer-events:none}:host:not([style*=top]){visibility:hidden}:host._delegated{scroll-timeline:none}:host:not(._anchored) .t-detector{display:none}.t-wrapper{z-index:-1;flex:1}.t-wrapper>*{padding:1rem}.t-detector{position:inherit;inset:anchor(top) 1rem calc(anchor(--t-scrollbar top) - 1rem);pointer-events:none;inline-size:calc(anchor-size(inline,-1px) + 1px);position-anchor:inherit;position-visibility:always}@supports (anchor-name: --t-scrollbar){.t-scrollbar{position:fixed;inset:anchor(top) anchor(right) anchor(bottom) anchor(left);position-anchor:--t-scrollbar;min-inline-size:0;min-block-size:0;margin:0}}\n"] }]
|
|
187
359
|
}] });
|
|
188
360
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
361
|
+
class TuiDropdownDriver extends BehaviorSubject {
|
|
362
|
+
constructor() {
|
|
363
|
+
super(false);
|
|
364
|
+
this.type = 'dropdown';
|
|
365
|
+
}
|
|
366
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriver, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
367
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriver }); }
|
|
368
|
+
}
|
|
369
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriver, decorators: [{
|
|
370
|
+
type: Injectable
|
|
371
|
+
}], ctorParameters: () => [] });
|
|
372
|
+
class TuiDropdownDriverDirective extends TuiDriverDirective {
|
|
373
|
+
constructor() {
|
|
374
|
+
super(...arguments);
|
|
375
|
+
this.type = 'dropdown';
|
|
376
|
+
}
|
|
377
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriverDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
378
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownDriverDirective, isStandalone: true, usesInheritance: true, ngImport: i0 }); }
|
|
379
|
+
}
|
|
380
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDriverDirective, decorators: [{
|
|
381
|
+
type: Directive
|
|
382
|
+
}] });
|
|
196
383
|
|
|
197
384
|
class TuiDropdownA11y {
|
|
198
385
|
constructor() {
|
|
@@ -257,79 +444,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
257
444
|
}]
|
|
258
445
|
}] });
|
|
259
446
|
|
|
260
|
-
class TuiDropdownPosition extends TuiPositionAccessor {
|
|
261
|
-
constructor() {
|
|
262
|
-
super(...arguments);
|
|
263
|
-
this.el = tuiInjectElement();
|
|
264
|
-
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
265
|
-
this.viewport = inject(TUI_VIEWPORT);
|
|
266
|
-
this.direction = new Subject();
|
|
267
|
-
this.type = 'dropdown';
|
|
268
|
-
this.accessor = tuiInjectAccessor(TuiRectAccessor, 'dropdown');
|
|
269
|
-
this.tuiDropdownDirectionChange = outputFromObservable(this.direction.pipe(distinctUntilChanged()));
|
|
270
|
-
}
|
|
271
|
-
getPosition({ width, height }) {
|
|
272
|
-
if (!width && !height) {
|
|
273
|
-
this.previous = undefined;
|
|
274
|
-
}
|
|
275
|
-
const hostRect = this.accessor.getClientRect();
|
|
276
|
-
const viewportRect = this.viewport.getClientRect();
|
|
277
|
-
const { minHeight, direction, offset, limitWidth } = this.options;
|
|
278
|
-
const align = this.getAlign(this.options.align);
|
|
279
|
-
const viewport = {
|
|
280
|
-
top: viewportRect.top - offset,
|
|
281
|
-
bottom: viewportRect.bottom + offset,
|
|
282
|
-
right: viewportRect.right - offset,
|
|
283
|
-
left: viewportRect.left + offset,
|
|
284
|
-
};
|
|
285
|
-
const previous = this.previous || direction || 'bottom';
|
|
286
|
-
const available = {
|
|
287
|
-
top: hostRect.top - 2 * offset - viewport.top,
|
|
288
|
-
bottom: viewport.bottom - hostRect.bottom - 2 * offset,
|
|
289
|
-
};
|
|
290
|
-
const rectWidth = limitWidth === 'fixed' ? hostRect.width : width;
|
|
291
|
-
const right = Math.max(hostRect.right - rectWidth, offset);
|
|
292
|
-
const left = hostRect.left + width < viewport.right ? hostRect.left : right;
|
|
293
|
-
const position = {
|
|
294
|
-
top: hostRect.top - offset - height,
|
|
295
|
-
bottom: hostRect.bottom + offset,
|
|
296
|
-
right: Math.max(viewport.left, right),
|
|
297
|
-
center: hostRect.left + hostRect.width / 2 + width / 2 < viewport.right
|
|
298
|
-
? hostRect.left + hostRect.width / 2 - width / 2
|
|
299
|
-
: right,
|
|
300
|
-
left: Math.max(viewport.left, left),
|
|
301
|
-
};
|
|
302
|
-
const better = available.top > available.bottom ? 'top' : 'bottom';
|
|
303
|
-
if ((available[previous] > minHeight && direction) ||
|
|
304
|
-
available[previous] > height) {
|
|
305
|
-
this.direction.next(previous);
|
|
306
|
-
return [position[align], position[previous]];
|
|
307
|
-
}
|
|
308
|
-
this.previous = better;
|
|
309
|
-
this.direction.next(better);
|
|
310
|
-
return [position[align], position[better]];
|
|
311
|
-
}
|
|
312
|
-
getAlign(align) {
|
|
313
|
-
const rtl = this.el.matches('[dir="rtl"] :scope');
|
|
314
|
-
if (rtl && align === 'start') {
|
|
315
|
-
return 'right';
|
|
316
|
-
}
|
|
317
|
-
if (rtl && align === 'end') {
|
|
318
|
-
return 'left';
|
|
319
|
-
}
|
|
320
|
-
if (align === 'center') {
|
|
321
|
-
return 'center';
|
|
322
|
-
}
|
|
323
|
-
return align === 'end' ? 'right' : 'left';
|
|
324
|
-
}
|
|
325
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
326
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownPosition, isStandalone: true, outputs: { tuiDropdownDirectionChange: "tuiDropdownDirectionChange" }, providers: [tuiAsPositionAccessor(TuiDropdownPosition)], usesInheritance: true, ngImport: i0 }); }
|
|
327
|
-
}
|
|
328
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, decorators: [{
|
|
329
|
-
type: Directive,
|
|
330
|
-
args: [{ providers: [tuiAsPositionAccessor(TuiDropdownPosition)] }]
|
|
331
|
-
}] });
|
|
332
|
-
|
|
333
447
|
class TuiDropdownDirective {
|
|
334
448
|
constructor() {
|
|
335
449
|
this.injector = inject(INJECTOR);
|
|
@@ -404,10 +518,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
404
518
|
TuiDropdownAnchor,
|
|
405
519
|
TuiDropdownDriverDirective,
|
|
406
520
|
{ directive: TuiDropdownA11y, inputs: ['tuiDropdownRole'] },
|
|
407
|
-
{
|
|
408
|
-
directive: TuiDropdownPosition,
|
|
409
|
-
outputs: ['tuiDropdownDirectionChange'],
|
|
410
|
-
},
|
|
521
|
+
{ directive: TuiDropdownPosition, outputs: ['tuiDropdownDirectionChange'] },
|
|
411
522
|
],
|
|
412
523
|
host: { '[class.tui-dropdown-open]': 'ref()' },
|
|
413
524
|
}]
|
|
@@ -588,12 +699,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
588
699
|
args: [{ selector: 'ng-template[tuiDropdown]' }]
|
|
589
700
|
}], ctorParameters: () => [] });
|
|
590
701
|
|
|
591
|
-
const STYLE = {
|
|
592
|
-
position: 'fixed',
|
|
593
|
-
blockSize: '1px',
|
|
594
|
-
inlineSize: '1px',
|
|
595
|
-
pointerEvents: 'none',
|
|
596
|
-
};
|
|
597
702
|
class TuiDropdownContext extends TuiRectAccessor {
|
|
598
703
|
constructor() {
|
|
599
704
|
super(...arguments);
|
|
@@ -616,14 +721,10 @@ class TuiDropdownContext extends TuiRectAccessor {
|
|
|
616
721
|
this.currentRect = EMPTY_CLIENT_RECT;
|
|
617
722
|
});
|
|
618
723
|
this.type = 'dropdown';
|
|
619
|
-
this.nativeElement =
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
const positionAnchor = this.el.getAttribute('data-tui-anchor');
|
|
624
|
-
const style = { ...STYLE, positionAnchor, anchorName };
|
|
625
|
-
Object.assign(this.nativeElement.style, style);
|
|
626
|
-
this.nativeElement.setAttribute('data-tui-anchor', anchorName);
|
|
724
|
+
this.nativeElement = tuiAnchorDelegate({
|
|
725
|
+
top: 'calc(anchor(top)',
|
|
726
|
+
left: 'calc(anchor(left)',
|
|
727
|
+
});
|
|
627
728
|
}
|
|
628
729
|
ngOnDestroy() {
|
|
629
730
|
this.nativeElement.parentNode?.removeChild(this.nativeElement);
|
|
@@ -635,8 +736,7 @@ class TuiDropdownContext extends TuiRectAccessor {
|
|
|
635
736
|
const { top, left } = this.el.getBoundingClientRect();
|
|
636
737
|
this.currentRect = tuiPointToClientRect(x, y);
|
|
637
738
|
this.nativeElement.style.top = `calc(anchor(top) + ${y - top}px)`;
|
|
638
|
-
this.nativeElement.style.left = `calc(anchor(left) + ${x - left}px)`;
|
|
639
|
-
this.doc.body.appendChild(this.nativeElement);
|
|
739
|
+
this.nativeElement.style.left = `calc(anchor(left, -100000px) + ${x - left}px)`;
|
|
640
740
|
this.driver.next(true);
|
|
641
741
|
}
|
|
642
742
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownContext, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
@@ -778,6 +878,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
778
878
|
class TuiDropdownPositionSided extends TuiPositionAccessor {
|
|
779
879
|
constructor() {
|
|
780
880
|
super(...arguments);
|
|
881
|
+
this.anchor = inject(TUI_DROPDOWN_ANCHOR, { optional: true });
|
|
781
882
|
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
782
883
|
this.viewport = inject(TUI_VIEWPORT);
|
|
783
884
|
this.vertical = inject(TuiDropdownPosition, { optional: true });
|
|
@@ -786,6 +887,23 @@ class TuiDropdownPositionSided extends TuiPositionAccessor {
|
|
|
786
887
|
this.tuiDropdownSidedOffset = input(4);
|
|
787
888
|
this.type = 'dropdown';
|
|
788
889
|
}
|
|
890
|
+
position(element) {
|
|
891
|
+
if (this.tuiDropdownSided() === false) {
|
|
892
|
+
this.vertical?.position(element);
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
const { direction, align, offset, minHeight, maxHeight } = this.options;
|
|
896
|
+
const horizontal = align === 'center' ? 'end' : align;
|
|
897
|
+
Object.assign(element.style, {
|
|
898
|
+
position: 'fixed',
|
|
899
|
+
visibility: 'visible',
|
|
900
|
+
positionAnchor: this.anchor?.nativeElement.dataset.tuiAnchor,
|
|
901
|
+
positionArea: `x-${horizontal} span-${direction || 'bottom'}`,
|
|
902
|
+
minBlockSize: `calc-size(fit-content, min(size, ${minHeight}px))`,
|
|
903
|
+
maxBlockSize: `min(calc-size(fit-content, size), ${maxHeight}px)`,
|
|
904
|
+
margin: `${-offset}px ${offset}px`,
|
|
905
|
+
});
|
|
906
|
+
}
|
|
789
907
|
getPosition(rect) {
|
|
790
908
|
if (this.tuiDropdownSided() === false && this.vertical) {
|
|
791
909
|
return this.vertical.getPosition(rect);
|
|
@@ -857,27 +975,17 @@ class TuiDropdownSelection extends TuiDriver {
|
|
|
857
975
|
const visible = valid || this.inDropdown(range);
|
|
858
976
|
const focus = tuiGetFocused(this.doc);
|
|
859
977
|
const textfield = focus && tuiIsTextfield(focus) && this.el.contains(focus);
|
|
978
|
+
const show = visible && textfield ? this.isCaretVisible(this.range) : visible;
|
|
860
979
|
this.updateAnchor();
|
|
861
|
-
return
|
|
980
|
+
return show;
|
|
862
981
|
}));
|
|
863
982
|
this.range = isPlatformBrowser(inject(PLATFORM_ID))
|
|
864
983
|
? new Range()
|
|
865
984
|
: {};
|
|
866
985
|
this.type = 'dropdown';
|
|
867
|
-
this.nativeElement =
|
|
986
|
+
this.nativeElement = tuiAnchorDelegate();
|
|
868
987
|
this.tuiDropdownSelection = input('');
|
|
869
988
|
this.tuiDropdownSelectionPosition = input('selection');
|
|
870
|
-
afterNextRender(() => {
|
|
871
|
-
const anchorName = `--${tuiGenerateId()}`;
|
|
872
|
-
Object.assign(this.nativeElement.style, {
|
|
873
|
-
position: 'fixed',
|
|
874
|
-
pointerEvents: 'none',
|
|
875
|
-
positionAnchor: this.el.dataset.tuiAnchor,
|
|
876
|
-
anchorName,
|
|
877
|
-
});
|
|
878
|
-
this.nativeElement.dataset.tuiAnchor = anchorName;
|
|
879
|
-
this.doc.body.appendChild(this.nativeElement);
|
|
880
|
-
});
|
|
881
989
|
}
|
|
882
990
|
ngOnDestroy() {
|
|
883
991
|
this.nativeElement.parentNode?.removeChild(this.nativeElement);
|
|
@@ -939,12 +1047,11 @@ class TuiDropdownSelection extends TuiDriver {
|
|
|
939
1047
|
}
|
|
940
1048
|
veryVerySadInputFix(element) {
|
|
941
1049
|
const { ghost = this.initGhost(this.ghostHost) } = this;
|
|
942
|
-
const {
|
|
1050
|
+
const { width, height } = this.ghostHost.getBoundingClientRect();
|
|
943
1051
|
const { selectionStart, selectionEnd, value } = element;
|
|
944
1052
|
const range = this.doc.createRange();
|
|
945
|
-
|
|
946
|
-
ghost.style.
|
|
947
|
-
ghost.style.left = tuiPx(left - hostRect.left);
|
|
1053
|
+
ghost.style.top = '0px';
|
|
1054
|
+
ghost.style.left = '0px';
|
|
948
1055
|
ghost.style.width = tuiPx(width);
|
|
949
1056
|
ghost.style.height = tuiPx(height);
|
|
950
1057
|
ghost.textContent = `${CHAR_ZERO_WIDTH_SPACE}${value}${CHAR_NO_BREAK_SPACE}`;
|
|
@@ -989,7 +1096,7 @@ class TuiDropdownSelection extends TuiDriver {
|
|
|
989
1096
|
const { top, left } = this.el.getBoundingClientRect();
|
|
990
1097
|
Object.assign(this.nativeElement.style, {
|
|
991
1098
|
top: `calc(anchor(top) + ${rect.top - top}px)`,
|
|
992
|
-
left: `calc(anchor(left) + ${rect.left - left}px)`,
|
|
1099
|
+
left: `calc(anchor(left, -100000px) + ${rect.left - left}px)`,
|
|
993
1100
|
blockSize: tuiPx(rect.height),
|
|
994
1101
|
inlineSize: tuiPx(rect.width),
|
|
995
1102
|
});
|