@taiga-ui/core 5.24.0 → 5.25.0-canary.2b025e7
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 +6 -1
- package/components/cell/cell-stretch.directive.d.ts +1 -1
- package/components/data-list/option.directive.d.ts +1 -1
- package/components/scrollbar/scroll-controls.component.d.ts +1 -1
- package/components/scrollbar/scroll-ref.directive.d.ts +2 -0
- package/components/scrollbar/scrollbar.component.d.ts +1 -2
- package/fesm2022/taiga-ui-core-classes.mjs +23 -7
- 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-calendar.mjs +1 -1
- package/fesm2022/taiga-ui-core-components-calendar.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-carousel.mjs +2 -2
- package/fesm2022/taiga-ui-core-components-carousel.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-cell.mjs +6 -9
- 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 +7 -7
- 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 +3 -3
- package/fesm2022/taiga-ui-core-components-root.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-scrollbar.mjs +34 -49
- package/fesm2022/taiga-ui-core-components-scrollbar.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-components-textfield.mjs +6 -5
- 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 +154 -140
- package/fesm2022/taiga-ui-core-portals-dropdown.mjs.map +1 -1
- package/fesm2022/taiga-ui-core-portals-hint.mjs +32 -34
- 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 +31 -9
- 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 +4 -4
- package/portals/dropdown/dropdown-anchor.directive.d.ts +5 -1
- package/portals/dropdown/dropdown-anchored.directive.d.ts +1 -1
- package/portals/dropdown/dropdown-context.directive.d.ts +3 -4
- package/portals/dropdown/dropdown-selection.directive.d.ts +1 -1
- package/portals/dropdown/dropdown.component.d.ts +3 -4
- package/portals/dropdown/dropdown.directive.d.ts +1 -0
- package/portals/dropdown/dropdown.providers.d.ts +1 -1
- package/portals/hint/hint-anchor.directive.d.ts +5 -1
- package/portals/hint/hint-pointer.directive.d.ts +1 -3
- package/portals/hint/hint.d.ts +1 -2
- package/tokens/date-format.d.ts +19 -0
- package/tokens/number-format.d.ts +18 -8
- package/utils/dom/anchor-delegate.d.ts +1 -0
- package/utils/dom/index.d.ts +1 -0
|
@@ -1,20 +1,20 @@
|
|
|
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 { Injectable, Directive, InjectionToken, Optional, Self, SkipSelf, inject,
|
|
5
|
-
import {
|
|
4
|
+
import { Injectable, Directive, InjectionToken, Optional, Self, SkipSelf, inject, computed, ChangeDetectionStrategy, Component, input, effect, ElementRef, INJECTOR, ChangeDetectorRef, signal, TemplateRef, contentChild, model, PLATFORM_ID, ViewContainerRef } from '@angular/core';
|
|
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 { TuiDriverDirective,
|
|
8
|
+
import { TuiDriverDirective, TuiRectAccessor, tuiProvideAccessor, TuiPositionAccessor, tuiAsRectAccessor, tuiInjectAccessor, tuiAsPositionAccessor, 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 { BehaviorSubject,
|
|
12
|
+
import { BehaviorSubject, takeWhile, map, Subject, distinctUntilChanged, 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';
|
|
17
|
+
import { TuiScrollbar, TuiScrollControls, TUI_SCROLL_REF } from '@taiga-ui/core/components/scrollbar';
|
|
18
18
|
import { TUI_VIEWPORT, 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';
|
|
@@ -99,84 +99,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
99
99
|
}]
|
|
100
100
|
}] });
|
|
101
101
|
|
|
102
|
-
class TuiDropdownPosition extends TuiPositionAccessor {
|
|
103
|
-
constructor() {
|
|
104
|
-
super(...arguments);
|
|
105
|
-
this.el = tuiInjectElement();
|
|
106
|
-
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
107
|
-
this.viewport = inject(TUI_VIEWPORT);
|
|
108
|
-
this.direction = new Subject();
|
|
109
|
-
this.type = 'dropdown';
|
|
110
|
-
this.accessor = tuiFallbackAccessor('dropdown')(inject(TuiRectAccessor, { self: true, optional: true }), { getClientRect: () => this.el.getBoundingClientRect() });
|
|
111
|
-
this.tuiDropdownDirectionChange = outputFromObservable(this.direction.pipe(distinctUntilChanged()));
|
|
112
|
-
}
|
|
113
|
-
getPosition({ width, height }) {
|
|
114
|
-
if (!width && !height) {
|
|
115
|
-
this.previous = undefined;
|
|
116
|
-
}
|
|
117
|
-
const hostRect = this.accessor.getClientRect();
|
|
118
|
-
const viewportRect = this.viewport.getClientRect();
|
|
119
|
-
const { minHeight, direction, offset, limitWidth } = this.options;
|
|
120
|
-
const align = this.getAlign(this.options.align);
|
|
121
|
-
const viewport = {
|
|
122
|
-
top: viewportRect.top - offset,
|
|
123
|
-
bottom: viewportRect.bottom + offset,
|
|
124
|
-
right: viewportRect.right - offset,
|
|
125
|
-
left: viewportRect.left + offset,
|
|
126
|
-
};
|
|
127
|
-
const previous = this.previous || direction || 'bottom';
|
|
128
|
-
const available = {
|
|
129
|
-
top: hostRect.top - 2 * offset - viewport.top,
|
|
130
|
-
bottom: viewport.bottom - hostRect.bottom - 2 * offset,
|
|
131
|
-
};
|
|
132
|
-
const rectWidth = limitWidth === 'fixed' ? hostRect.width : width;
|
|
133
|
-
const right = Math.max(hostRect.right - rectWidth, offset);
|
|
134
|
-
const left = hostRect.left + width < viewport.right ? hostRect.left : right;
|
|
135
|
-
const position = {
|
|
136
|
-
top: hostRect.top - offset - height,
|
|
137
|
-
bottom: hostRect.bottom + offset,
|
|
138
|
-
right: Math.max(viewport.left, right),
|
|
139
|
-
center: hostRect.left + hostRect.width / 2 + width / 2 < viewport.right
|
|
140
|
-
? hostRect.left + hostRect.width / 2 - width / 2
|
|
141
|
-
: right,
|
|
142
|
-
left: Math.max(viewport.left, left),
|
|
143
|
-
};
|
|
144
|
-
const better = available.top > available.bottom ? 'top' : 'bottom';
|
|
145
|
-
if ((available[previous] > minHeight && direction) ||
|
|
146
|
-
available[previous] > height) {
|
|
147
|
-
this.direction.next(previous);
|
|
148
|
-
return [position[align], position[previous]];
|
|
149
|
-
}
|
|
150
|
-
this.previous = better;
|
|
151
|
-
this.direction.next(better);
|
|
152
|
-
return [position[align], position[better]];
|
|
153
|
-
}
|
|
154
|
-
getAlign(align) {
|
|
155
|
-
const rtl = this.el.matches('[dir="rtl"] :scope');
|
|
156
|
-
if (rtl && align === 'start') {
|
|
157
|
-
return 'right';
|
|
158
|
-
}
|
|
159
|
-
if (rtl && align === 'end') {
|
|
160
|
-
return 'left';
|
|
161
|
-
}
|
|
162
|
-
if (align === 'center') {
|
|
163
|
-
return 'center';
|
|
164
|
-
}
|
|
165
|
-
return align === 'end' ? 'right' : 'left';
|
|
166
|
-
}
|
|
167
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
168
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownPosition, isStandalone: true, outputs: { tuiDropdownDirectionChange: "tuiDropdownDirectionChange" }, usesInheritance: true, ngImport: i0 }); }
|
|
169
|
-
}
|
|
170
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, decorators: [{
|
|
171
|
-
type: Directive
|
|
172
|
-
}] });
|
|
173
|
-
|
|
174
102
|
const MAX_WIDTH_GAP = 16; // 8px min gap from each side
|
|
175
103
|
class TuiDropdownAnchored {
|
|
176
104
|
constructor() {
|
|
177
105
|
this.el = tuiInjectElement();
|
|
178
106
|
this.directive = inject(TuiDropdownDirective);
|
|
179
|
-
this.
|
|
107
|
+
this.rect = inject(TuiRectAccessor);
|
|
180
108
|
this.viewport = inject(TUI_VIEWPORT);
|
|
181
109
|
this.vvs = inject(TuiVisualViewportService);
|
|
182
110
|
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
@@ -194,7 +122,7 @@ class TuiDropdownAnchored {
|
|
|
194
122
|
const { maxHeight, minHeight, offset, limitWidth } = this.options;
|
|
195
123
|
const parent = this.el.offsetParent?.getBoundingClientRect() || EMPTY_CLIENT_RECT;
|
|
196
124
|
const { left = 0, top = 0 } = this.position === 'fixed' ? {} : parent;
|
|
197
|
-
const rect = this.
|
|
125
|
+
const rect = this.rect.getClientRect();
|
|
198
126
|
const viewport = this.viewport.getClientRect();
|
|
199
127
|
const zoom = this.directive.el.currentCSSZoom || 1;
|
|
200
128
|
const above = rect.top - viewport.top - 2 * offset;
|
|
@@ -218,8 +146,8 @@ class TuiDropdownAnchored {
|
|
|
218
146
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownAnchored, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
219
147
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownAnchored, isStandalone: true, providers: [
|
|
220
148
|
TuiPositionService,
|
|
221
|
-
|
|
222
|
-
|
|
149
|
+
tuiProvideAccessor(TuiPositionAccessor, 'dropdown'),
|
|
150
|
+
tuiProvideAccessor(TuiRectAccessor, 'dropdown'),
|
|
223
151
|
], ngImport: i0 }); }
|
|
224
152
|
}
|
|
225
153
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownAnchored, decorators: [{
|
|
@@ -227,19 +155,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
227
155
|
args: [{
|
|
228
156
|
providers: [
|
|
229
157
|
TuiPositionService,
|
|
230
|
-
|
|
231
|
-
|
|
158
|
+
tuiProvideAccessor(TuiPositionAccessor, 'dropdown'),
|
|
159
|
+
tuiProvideAccessor(TuiRectAccessor, 'dropdown'),
|
|
232
160
|
],
|
|
233
161
|
}]
|
|
234
162
|
}] });
|
|
235
163
|
|
|
236
164
|
/**
|
|
237
|
-
*
|
|
238
|
-
* This component is used to show template in a portal
|
|
239
|
-
* using default style of white rounded box with a shadow
|
|
165
|
+
* TODO: Remove extends TuiScrollbar in v6 when TuiScrollable is dropped
|
|
240
166
|
*/
|
|
241
|
-
class TuiDropdownComponent {
|
|
167
|
+
class TuiDropdownComponent extends TuiScrollbar {
|
|
242
168
|
constructor() {
|
|
169
|
+
super(...arguments);
|
|
243
170
|
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
244
171
|
this.directive = inject(TuiDropdownDirective);
|
|
245
172
|
this.context = inject(TUI_DROPDOWN_CONTEXT, { optional: true });
|
|
@@ -247,15 +174,48 @@ class TuiDropdownComponent {
|
|
|
247
174
|
this.theme = computed((_ = this.darkMode()) => this.directive.el.closest('[tuiTheme]')?.getAttribute('tuiTheme'));
|
|
248
175
|
this.close = () => this.directive.toggle(false);
|
|
249
176
|
}
|
|
250
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownComponent, deps:
|
|
251
|
-
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()"
|
|
177
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
178
|
+
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: [
|
|
179
|
+
{
|
|
180
|
+
provide: TUI_SCROLL_REF,
|
|
181
|
+
useFactory: () => inject(TuiDropdownComponent).browserScrollRef,
|
|
182
|
+
},
|
|
183
|
+
], usesInheritance: true, hostDirectives: [{ directive: i1.TuiActiveZone }, { directive: i2.TuiAnimated }, { directive: TuiDropdownAnchored }], ngImport: i0, template: `
|
|
184
|
+
<tui-scroll-controls class="t-scrollbar" />
|
|
185
|
+
<div class="t-wrapper">
|
|
186
|
+
<div
|
|
187
|
+
*polymorpheusOutlet="
|
|
188
|
+
directive.content() as text;
|
|
189
|
+
context: {$implicit: close}
|
|
190
|
+
"
|
|
191
|
+
[innerHTML]="text"
|
|
192
|
+
></div>
|
|
193
|
+
</div>
|
|
194
|
+
`, 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-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}.t-wrapper{z-index:-1;flex:1}.t-wrapper>*{padding:1rem}@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 }); }
|
|
252
195
|
}
|
|
253
196
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownComponent, decorators: [{
|
|
254
197
|
type: Component,
|
|
255
|
-
args: [{ selector: 'tui-dropdown', imports: [PolymorpheusOutlet,
|
|
198
|
+
args: [{ selector: 'tui-dropdown', imports: [PolymorpheusOutlet, TuiScrollControls], template: `
|
|
199
|
+
<tui-scroll-controls class="t-scrollbar" />
|
|
200
|
+
<div class="t-wrapper">
|
|
201
|
+
<div
|
|
202
|
+
*polymorpheusOutlet="
|
|
203
|
+
directive.content() as text;
|
|
204
|
+
context: {$implicit: close}
|
|
205
|
+
"
|
|
206
|
+
[innerHTML]="text"
|
|
207
|
+
></div>
|
|
208
|
+
</div>
|
|
209
|
+
`, changeDetection: ChangeDetectionStrategy.Default, providers: [
|
|
210
|
+
{
|
|
211
|
+
provide: TUI_SCROLL_REF,
|
|
212
|
+
useFactory: () => inject(TuiDropdownComponent).browserScrollRef,
|
|
213
|
+
},
|
|
214
|
+
], hostDirectives: [TuiActiveZone, TuiAnimated, TuiDropdownAnchored], host: {
|
|
256
215
|
'[attr.data-appearance]': 'options.appearance',
|
|
257
216
|
'[attr.tuiTheme]': 'theme()',
|
|
258
|
-
|
|
217
|
+
'[style.max-block-size.px]': 'options.maxHeight',
|
|
218
|
+
}, 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-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}.t-wrapper{z-index:-1;flex:1}.t-wrapper>*{padding:1rem}@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"] }]
|
|
259
219
|
}] });
|
|
260
220
|
|
|
261
221
|
/**
|
|
@@ -297,20 +257,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
297
257
|
args: [{ selector: '[tuiDropdownA11y]' }]
|
|
298
258
|
}] });
|
|
299
259
|
|
|
300
|
-
class TuiDropdownAnchor {
|
|
260
|
+
class TuiDropdownAnchor extends TuiRectAccessor {
|
|
301
261
|
constructor() {
|
|
262
|
+
super(...arguments);
|
|
263
|
+
this.el = tuiInjectElement();
|
|
302
264
|
this.anchor = `--${tuiGenerateId()}`;
|
|
265
|
+
this.type = 'dropdown';
|
|
266
|
+
}
|
|
267
|
+
getClientRect() {
|
|
268
|
+
return this.el.getBoundingClientRect();
|
|
303
269
|
}
|
|
304
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownAnchor, deps:
|
|
270
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownAnchor, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
305
271
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownAnchor, isStandalone: true, host: { properties: { "attr.data-tui-anchor": "anchor", "style.anchor-name": "anchor" } }, providers: [
|
|
272
|
+
tuiAsRectAccessor(TuiDropdownAnchor),
|
|
306
273
|
tuiProvide(TUI_DROPDOWN_HOST, ElementRef),
|
|
307
274
|
tuiProvide(TUI_DROPDOWN_ANCHOR, ElementRef),
|
|
308
|
-
], ngImport: i0 }); }
|
|
275
|
+
], usesInheritance: true, ngImport: i0 }); }
|
|
309
276
|
}
|
|
310
277
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownAnchor, decorators: [{
|
|
311
278
|
type: Directive,
|
|
312
279
|
args: [{
|
|
313
280
|
providers: [
|
|
281
|
+
tuiAsRectAccessor(TuiDropdownAnchor),
|
|
314
282
|
tuiProvide(TUI_DROPDOWN_HOST, ElementRef),
|
|
315
283
|
tuiProvide(TUI_DROPDOWN_ANCHOR, ElementRef),
|
|
316
284
|
],
|
|
@@ -321,6 +289,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
321
289
|
}]
|
|
322
290
|
}] });
|
|
323
291
|
|
|
292
|
+
class TuiDropdownPosition extends TuiPositionAccessor {
|
|
293
|
+
constructor() {
|
|
294
|
+
super(...arguments);
|
|
295
|
+
this.el = tuiInjectElement();
|
|
296
|
+
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
297
|
+
this.viewport = inject(TUI_VIEWPORT);
|
|
298
|
+
this.direction = new Subject();
|
|
299
|
+
this.type = 'dropdown';
|
|
300
|
+
this.accessor = tuiInjectAccessor(TuiRectAccessor, 'dropdown');
|
|
301
|
+
this.tuiDropdownDirectionChange = outputFromObservable(this.direction.pipe(distinctUntilChanged()));
|
|
302
|
+
}
|
|
303
|
+
getPosition({ width, height }) {
|
|
304
|
+
if (!width && !height) {
|
|
305
|
+
this.previous = undefined;
|
|
306
|
+
}
|
|
307
|
+
const hostRect = this.accessor.getClientRect();
|
|
308
|
+
const viewportRect = this.viewport.getClientRect();
|
|
309
|
+
const { minHeight, direction, offset, limitWidth } = this.options;
|
|
310
|
+
const align = this.getAlign(this.options.align);
|
|
311
|
+
const previous = this.previous || direction || 'bottom';
|
|
312
|
+
const viewport = {
|
|
313
|
+
top: viewportRect.top - offset,
|
|
314
|
+
bottom: viewportRect.bottom + offset,
|
|
315
|
+
right: viewportRect.right - offset,
|
|
316
|
+
left: viewportRect.left + offset,
|
|
317
|
+
};
|
|
318
|
+
const available = {
|
|
319
|
+
top: hostRect.top - 2 * offset - viewport.top,
|
|
320
|
+
bottom: viewport.bottom - hostRect.bottom - 2 * offset,
|
|
321
|
+
};
|
|
322
|
+
const rectWidth = limitWidth === 'fixed' ? hostRect.width : width;
|
|
323
|
+
const right = Math.max(hostRect.right - rectWidth, offset);
|
|
324
|
+
const left = hostRect.left + width < viewport.right ? hostRect.left : right;
|
|
325
|
+
const better = available.top > available.bottom ? 'top' : 'bottom';
|
|
326
|
+
const position = {
|
|
327
|
+
top: hostRect.top - offset - height,
|
|
328
|
+
bottom: hostRect.bottom + offset,
|
|
329
|
+
right: Math.max(viewport.left, right),
|
|
330
|
+
center: hostRect.left + hostRect.width / 2 + width / 2 < viewport.right
|
|
331
|
+
? hostRect.left + hostRect.width / 2 - width / 2
|
|
332
|
+
: right,
|
|
333
|
+
left: Math.max(viewport.left, left),
|
|
334
|
+
};
|
|
335
|
+
if ((available[previous] > minHeight && direction) ||
|
|
336
|
+
available[previous] > height) {
|
|
337
|
+
this.direction.next(previous);
|
|
338
|
+
return [position[align], position[previous]];
|
|
339
|
+
}
|
|
340
|
+
this.previous = better;
|
|
341
|
+
this.direction.next(better);
|
|
342
|
+
return [position[align], position[better]];
|
|
343
|
+
}
|
|
344
|
+
getAlign(align) {
|
|
345
|
+
const rtl = this.el.matches('[dir="rtl"] :scope');
|
|
346
|
+
if (rtl && align === 'start') {
|
|
347
|
+
return 'right';
|
|
348
|
+
}
|
|
349
|
+
if (rtl && align === 'end') {
|
|
350
|
+
return 'left';
|
|
351
|
+
}
|
|
352
|
+
if (align === 'center') {
|
|
353
|
+
return 'center';
|
|
354
|
+
}
|
|
355
|
+
return align === 'end' ? 'right' : 'left';
|
|
356
|
+
}
|
|
357
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
358
|
+
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 }); }
|
|
359
|
+
}
|
|
360
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPosition, decorators: [{
|
|
361
|
+
type: Directive,
|
|
362
|
+
args: [{ providers: [tuiAsPositionAccessor(TuiDropdownPosition)] }]
|
|
363
|
+
}] });
|
|
364
|
+
|
|
324
365
|
class TuiDropdownDirective {
|
|
325
366
|
constructor() {
|
|
326
367
|
this.injector = inject(INJECTOR);
|
|
@@ -350,11 +391,12 @@ class TuiDropdownDirective {
|
|
|
350
391
|
: content,
|
|
351
392
|
});
|
|
352
393
|
}
|
|
394
|
+
/** @deprecated remove in v6 */
|
|
353
395
|
get accessor() {
|
|
354
396
|
const accessors = this.injector.get(TuiRectAccessor, null, {
|
|
355
397
|
self: true,
|
|
356
398
|
});
|
|
357
|
-
return
|
|
399
|
+
return ([...(accessors || [])].reverse().find(({ type }) => type === 'dropdown') || this);
|
|
358
400
|
}
|
|
359
401
|
get position() {
|
|
360
402
|
return tuiCheckFixedPosition(this.el) ? 'fixed' : 'absolute';
|
|
@@ -394,10 +436,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
394
436
|
TuiDropdownAnchor,
|
|
395
437
|
TuiDropdownDriverDirective,
|
|
396
438
|
{ directive: TuiDropdownA11y, inputs: ['tuiDropdownRole'] },
|
|
397
|
-
{
|
|
398
|
-
directive: TuiDropdownPosition,
|
|
399
|
-
outputs: ['tuiDropdownDirectionChange'],
|
|
400
|
-
},
|
|
439
|
+
{ directive: TuiDropdownPosition, outputs: ['tuiDropdownDirectionChange'] },
|
|
401
440
|
],
|
|
402
441
|
host: { '[class.tui-dropdown-open]': 'ref()' },
|
|
403
442
|
}]
|
|
@@ -578,12 +617,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
|
|
|
578
617
|
args: [{ selector: 'ng-template[tuiDropdown]' }]
|
|
579
618
|
}], ctorParameters: () => [] });
|
|
580
619
|
|
|
581
|
-
const STYLE = {
|
|
582
|
-
position: 'fixed',
|
|
583
|
-
blockSize: '1px',
|
|
584
|
-
inlineSize: '1px',
|
|
585
|
-
pointerEvents: 'none',
|
|
586
|
-
};
|
|
587
620
|
class TuiDropdownContext extends TuiRectAccessor {
|
|
588
621
|
constructor() {
|
|
589
622
|
super(...arguments);
|
|
@@ -606,14 +639,7 @@ class TuiDropdownContext extends TuiRectAccessor {
|
|
|
606
639
|
this.currentRect = EMPTY_CLIENT_RECT;
|
|
607
640
|
});
|
|
608
641
|
this.type = 'dropdown';
|
|
609
|
-
this.nativeElement =
|
|
610
|
-
}
|
|
611
|
-
ngAfterViewInit() {
|
|
612
|
-
const anchorName = `--${tuiGenerateId()}`;
|
|
613
|
-
const positionAnchor = this.el.getAttribute('data-tui-anchor');
|
|
614
|
-
const style = { ...STYLE, positionAnchor, anchorName };
|
|
615
|
-
Object.assign(this.nativeElement.style, style);
|
|
616
|
-
this.nativeElement.setAttribute('data-tui-anchor', anchorName);
|
|
642
|
+
this.nativeElement = tuiAnchorDelegate({ width: '1px', height: '1px' });
|
|
617
643
|
}
|
|
618
644
|
ngOnDestroy() {
|
|
619
645
|
this.nativeElement.parentNode?.removeChild(this.nativeElement);
|
|
@@ -626,7 +652,6 @@ class TuiDropdownContext extends TuiRectAccessor {
|
|
|
626
652
|
this.currentRect = tuiPointToClientRect(x, y);
|
|
627
653
|
this.nativeElement.style.top = `calc(anchor(top) + ${y - top}px)`;
|
|
628
654
|
this.nativeElement.style.left = `calc(anchor(left) + ${x - left}px)`;
|
|
629
|
-
this.doc.body.appendChild(this.nativeElement);
|
|
630
655
|
this.driver.next(true);
|
|
631
656
|
}
|
|
632
657
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownContext, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
@@ -770,21 +795,21 @@ class TuiDropdownPositionSided extends TuiPositionAccessor {
|
|
|
770
795
|
super(...arguments);
|
|
771
796
|
this.options = inject(TUI_DROPDOWN_OPTIONS);
|
|
772
797
|
this.viewport = inject(TUI_VIEWPORT);
|
|
773
|
-
this.vertical = inject(TuiDropdownPosition);
|
|
798
|
+
this.vertical = inject(TuiDropdownPosition, { optional: true });
|
|
774
799
|
this.previous = this.options.direction || 'bottom';
|
|
775
800
|
this.tuiDropdownSided = input('');
|
|
776
801
|
this.tuiDropdownSidedOffset = input(4);
|
|
777
802
|
this.type = 'dropdown';
|
|
778
803
|
}
|
|
779
804
|
getPosition(rect) {
|
|
780
|
-
if (this.tuiDropdownSided() === false) {
|
|
805
|
+
if (this.tuiDropdownSided() === false && this.vertical) {
|
|
781
806
|
return this.vertical.getPosition(rect);
|
|
782
807
|
}
|
|
783
808
|
const { height, width } = rect;
|
|
784
|
-
const hostRect = this.vertical.
|
|
809
|
+
const hostRect = this.vertical?.accessor.getClientRect() ?? EMPTY_CLIENT_RECT;
|
|
785
810
|
const viewport = this.viewport.getClientRect();
|
|
786
811
|
const { direction, offset } = this.options;
|
|
787
|
-
const adjusted = this.vertical
|
|
812
|
+
const adjusted = this.vertical?.getAlign(this.options.align) || 'center';
|
|
788
813
|
const align = adjusted === 'center' ? 'left' : adjusted;
|
|
789
814
|
const available = {
|
|
790
815
|
top: hostRect.bottom - viewport.top,
|
|
@@ -803,21 +828,21 @@ class TuiDropdownPositionSided extends TuiPositionAccessor {
|
|
|
803
828
|
const left = available[align] > width ? position[align] : maxLeft;
|
|
804
829
|
if ((available[this.previous] > height && direction) ||
|
|
805
830
|
this.previous === better) {
|
|
806
|
-
this.vertical
|
|
831
|
+
this.vertical?.direction.next(this.previous);
|
|
807
832
|
return [left, position[this.previous]];
|
|
808
833
|
}
|
|
809
834
|
this.previous = better;
|
|
810
|
-
this.vertical
|
|
835
|
+
this.vertical?.direction.next(better);
|
|
811
836
|
return [left, position[better]];
|
|
812
837
|
}
|
|
813
838
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPositionSided, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
814
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.25", type: TuiDropdownPositionSided, isStandalone: true, selector: "[tuiDropdownSided]", inputs: { tuiDropdownSided: { classPropertyName: "tuiDropdownSided", publicName: "tuiDropdownSided", isSignal: true, isRequired: false, transformFunction: null }, tuiDropdownSidedOffset: { classPropertyName: "tuiDropdownSidedOffset", publicName: "tuiDropdownSidedOffset", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
839
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.25", type: TuiDropdownPositionSided, isStandalone: true, selector: "[tuiDropdownSided]", inputs: { tuiDropdownSided: { classPropertyName: "tuiDropdownSided", publicName: "tuiDropdownSided", isSignal: true, isRequired: false, transformFunction: null }, tuiDropdownSidedOffset: { classPropertyName: "tuiDropdownSidedOffset", publicName: "tuiDropdownSidedOffset", isSignal: true, isRequired: false, transformFunction: null } }, providers: [tuiAsPositionAccessor(TuiDropdownPositionSided)], usesInheritance: true, ngImport: i0 }); }
|
|
815
840
|
}
|
|
816
841
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownPositionSided, decorators: [{
|
|
817
842
|
type: Directive,
|
|
818
843
|
args: [{
|
|
819
844
|
selector: '[tuiDropdownSided]',
|
|
820
|
-
providers: [
|
|
845
|
+
providers: [tuiAsPositionAccessor(TuiDropdownPositionSided)],
|
|
821
846
|
}]
|
|
822
847
|
}] });
|
|
823
848
|
|
|
@@ -847,27 +872,17 @@ class TuiDropdownSelection extends TuiDriver {
|
|
|
847
872
|
const visible = valid || this.inDropdown(range);
|
|
848
873
|
const focus = tuiGetFocused(this.doc);
|
|
849
874
|
const textfield = focus && tuiIsTextfield(focus) && this.el.contains(focus);
|
|
875
|
+
const show = visible && textfield ? this.isCaretVisible(this.range) : visible;
|
|
850
876
|
this.updateAnchor();
|
|
851
|
-
return
|
|
877
|
+
return show;
|
|
852
878
|
}));
|
|
853
879
|
this.range = isPlatformBrowser(inject(PLATFORM_ID))
|
|
854
880
|
? new Range()
|
|
855
881
|
: {};
|
|
856
882
|
this.type = 'dropdown';
|
|
857
|
-
this.nativeElement =
|
|
883
|
+
this.nativeElement = tuiAnchorDelegate();
|
|
858
884
|
this.tuiDropdownSelection = input('');
|
|
859
885
|
this.tuiDropdownSelectionPosition = input('selection');
|
|
860
|
-
afterNextRender(() => {
|
|
861
|
-
const anchorName = `--${tuiGenerateId()}`;
|
|
862
|
-
Object.assign(this.nativeElement.style, {
|
|
863
|
-
position: 'fixed',
|
|
864
|
-
pointerEvents: 'none',
|
|
865
|
-
positionAnchor: this.el.dataset.tuiAnchor,
|
|
866
|
-
anchorName,
|
|
867
|
-
});
|
|
868
|
-
this.nativeElement.dataset.tuiAnchor = anchorName;
|
|
869
|
-
this.doc.body.appendChild(this.nativeElement);
|
|
870
|
-
});
|
|
871
886
|
}
|
|
872
887
|
ngOnDestroy() {
|
|
873
888
|
this.nativeElement.parentNode?.removeChild(this.nativeElement);
|
|
@@ -929,12 +944,11 @@ class TuiDropdownSelection extends TuiDriver {
|
|
|
929
944
|
}
|
|
930
945
|
veryVerySadInputFix(element) {
|
|
931
946
|
const { ghost = this.initGhost(this.ghostHost) } = this;
|
|
932
|
-
const {
|
|
947
|
+
const { width, height } = this.ghostHost.getBoundingClientRect();
|
|
933
948
|
const { selectionStart, selectionEnd, value } = element;
|
|
934
949
|
const range = this.doc.createRange();
|
|
935
|
-
|
|
936
|
-
ghost.style.
|
|
937
|
-
ghost.style.left = tuiPx(left - hostRect.left);
|
|
950
|
+
ghost.style.top = '0px';
|
|
951
|
+
ghost.style.left = '0px';
|
|
938
952
|
ghost.style.width = tuiPx(width);
|
|
939
953
|
ghost.style.height = tuiPx(height);
|
|
940
954
|
ghost.textContent = `${CHAR_ZERO_WIDTH_SPACE}${value}${CHAR_NO_BREAK_SPACE}`;
|