@taiga-ui/core 5.22.0 → 5.23.0-canary.0a07bcd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/components/error/error.directive.d.ts +3 -3
  2. package/fesm2022/taiga-ui-core-components-button.mjs +2 -2
  3. package/fesm2022/taiga-ui-core-components-button.mjs.map +1 -1
  4. package/fesm2022/taiga-ui-core-components-cell.mjs +3 -3
  5. package/fesm2022/taiga-ui-core-components-cell.mjs.map +1 -1
  6. package/fesm2022/taiga-ui-core-components-checkbox.mjs +2 -2
  7. package/fesm2022/taiga-ui-core-components-checkbox.mjs.map +1 -1
  8. package/fesm2022/taiga-ui-core-components-data-list.mjs +4 -4
  9. package/fesm2022/taiga-ui-core-components-data-list.mjs.map +1 -1
  10. package/fesm2022/taiga-ui-core-components-error.mjs +4 -4
  11. package/fesm2022/taiga-ui-core-components-error.mjs.map +1 -1
  12. package/fesm2022/taiga-ui-core-components-icon.mjs +2 -2
  13. package/fesm2022/taiga-ui-core-components-icon.mjs.map +1 -1
  14. package/fesm2022/taiga-ui-core-components-label.mjs +3 -3
  15. package/fesm2022/taiga-ui-core-components-label.mjs.map +1 -1
  16. package/fesm2022/taiga-ui-core-components-link.mjs +2 -2
  17. package/fesm2022/taiga-ui-core-components-link.mjs.map +1 -1
  18. package/fesm2022/taiga-ui-core-components-notification.mjs +2 -2
  19. package/fesm2022/taiga-ui-core-components-notification.mjs.map +1 -1
  20. package/fesm2022/taiga-ui-core-components-radio.mjs +2 -2
  21. package/fesm2022/taiga-ui-core-components-radio.mjs.map +1 -1
  22. package/fesm2022/taiga-ui-core-components-root.mjs +3 -3
  23. package/fesm2022/taiga-ui-core-components-root.mjs.map +1 -1
  24. package/fesm2022/taiga-ui-core-components-scrollbar.mjs +3 -3
  25. package/fesm2022/taiga-ui-core-components-scrollbar.mjs.map +1 -1
  26. package/fesm2022/taiga-ui-core-components-textfield.mjs +5 -5
  27. package/fesm2022/taiga-ui-core-components-textfield.mjs.map +1 -1
  28. package/fesm2022/taiga-ui-core-components-title.mjs +3 -3
  29. package/fesm2022/taiga-ui-core-components-title.mjs.map +1 -1
  30. package/fesm2022/taiga-ui-core-directives-appearance.mjs +3 -3
  31. package/fesm2022/taiga-ui-core-directives-appearance.mjs.map +1 -1
  32. package/fesm2022/taiga-ui-core-directives-group.mjs +3 -3
  33. package/fesm2022/taiga-ui-core-directives-group.mjs.map +1 -1
  34. package/fesm2022/taiga-ui-core-directives-icons.mjs +3 -3
  35. package/fesm2022/taiga-ui-core-directives-icons.mjs.map +1 -1
  36. package/fesm2022/taiga-ui-core-portals-alert.mjs +3 -3
  37. package/fesm2022/taiga-ui-core-portals-alert.mjs.map +1 -1
  38. package/fesm2022/taiga-ui-core-portals-dialog.mjs +2 -2
  39. package/fesm2022/taiga-ui-core-portals-dialog.mjs.map +1 -1
  40. package/fesm2022/taiga-ui-core-portals-dropdown.mjs +86 -17
  41. package/fesm2022/taiga-ui-core-portals-dropdown.mjs.map +1 -1
  42. package/fesm2022/taiga-ui-core-portals-modal.mjs +3 -3
  43. package/fesm2022/taiga-ui-core-portals-modal.mjs.map +1 -1
  44. package/fesm2022/taiga-ui-core-tokens.mjs +4 -2
  45. package/fesm2022/taiga-ui-core-tokens.mjs.map +1 -1
  46. package/package.json +12 -12
  47. package/portals/dialog/dialog.options.d.ts +2 -2
  48. package/portals/dropdown/dropdown-context.directive.d.ts +5 -1
  49. package/portals/dropdown/dropdown-host.directive.d.ts +6 -0
  50. package/portals/dropdown/dropdown-selection.directive.d.ts +5 -3
  51. package/portals/dropdown/dropdown.directive.d.ts +5 -4
  52. package/portals/dropdown/dropdown.providers.d.ts +1 -0
  53. package/portals/dropdown/index.d.ts +1 -0
  54. package/tokens/anchor-support.d.ts +2 -0
  55. package/tokens/index.d.ts +1 -0
  56. package/tokens/textfield.d.ts +2 -2
@@ -1,7 +1,7 @@
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, forwardRef, computed, ChangeDetectionStrategy, Component, input, effect, INJECTOR, ChangeDetectorRef, signal, TemplateRef, ElementRef, contentChild, model, PLATFORM_ID, ViewContainerRef } from '@angular/core';
4
+ import { Injectable, Directive, InjectionToken, Optional, Self, SkipSelf, inject, forwardRef, computed, ChangeDetectionStrategy, Component, input, effect, ElementRef, INJECTOR, ChangeDetectorRef, signal, TemplateRef, contentChild, model, PLATFORM_ID, ViewContainerRef, afterNextRender } from '@angular/core';
5
5
  import { outputFromObservable, takeUntilDestroyed, 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';
@@ -264,6 +264,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
264
264
  const TUI_DROPDOWN_COMPONENT = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_COMPONENT' : '', { factory: () => TuiDropdownComponent });
265
265
  const TUI_DROPDOWN_CONTEXT = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_CONTEXT' : '');
266
266
  const TUI_DROPDOWN_HOST = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_HOST' : '');
267
+ const TUI_DROPDOWN_ANCHOR = new InjectionToken(ngDevMode ? 'TUI_DROPDOWN_ANCHOR' : '');
267
268
 
268
269
  class TuiDropdownA11y {
269
270
  constructor() {
@@ -296,6 +297,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
296
297
  args: [{ selector: '[tuiDropdownA11y]' }]
297
298
  }] });
298
299
 
300
+ class TuiDropdownHost {
301
+ constructor() {
302
+ this.anchor = `--${tuiGenerateId()}`;
303
+ }
304
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownHost, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
305
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: TuiDropdownHost, isStandalone: true, host: { properties: { "attr.data-tui-anchor": "anchor", "style.anchor-name": "anchor" } }, providers: [
306
+ tuiProvide(TUI_DROPDOWN_HOST, ElementRef),
307
+ tuiProvide(TUI_DROPDOWN_ANCHOR, ElementRef),
308
+ ], ngImport: i0 }); }
309
+ }
310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownHost, decorators: [{
311
+ type: Directive,
312
+ args: [{
313
+ providers: [
314
+ tuiProvide(TUI_DROPDOWN_HOST, ElementRef),
315
+ tuiProvide(TUI_DROPDOWN_ANCHOR, ElementRef),
316
+ ],
317
+ host: {
318
+ '[attr.data-tui-anchor]': 'anchor',
319
+ '[style.anchor-name]': 'anchor',
320
+ },
321
+ }]
322
+ }] });
323
+
299
324
  class TuiDropdownDirective {
300
325
  constructor() {
301
326
  this.injector = inject(INJECTOR);
@@ -357,21 +382,16 @@ class TuiDropdownDirective {
357
382
  this.drivers.forEach((driver) => driver?.next(show));
358
383
  }
359
384
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
360
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.25", type: TuiDropdownDirective, isStandalone: true, selector: "[tuiDropdown]:not(ng-container):not(ng-template)", inputs: { content: { classPropertyName: "content", publicName: "tuiDropdown", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.tui-dropdown-open": "ref()" } }, providers: [
361
- tuiAsVehicle(TuiDropdownDirective),
362
- tuiProvide(TUI_DROPDOWN_HOST, ElementRef),
363
- ], exportAs: ["tuiDropdown"], hostDirectives: [{ directive: TuiDropdownDriverDirective }, { directive: TuiDropdownA11y, inputs: ["tuiDropdownRole", "tuiDropdownRole"] }, { directive: TuiDropdownPosition, outputs: ["tuiDropdownDirectionChange", "tuiDropdownDirectionChange"] }], ngImport: i0 }); }
385
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.25", type: TuiDropdownDirective, isStandalone: true, selector: "[tuiDropdown]:not(ng-container):not(ng-template)", inputs: { content: { classPropertyName: "content", publicName: "tuiDropdown", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.tui-dropdown-open": "ref()" } }, providers: [tuiAsVehicle(TuiDropdownDirective)], exportAs: ["tuiDropdown"], hostDirectives: [{ directive: TuiDropdownHost }, { directive: TuiDropdownDriverDirective }, { directive: TuiDropdownA11y, inputs: ["tuiDropdownRole", "tuiDropdownRole"] }, { directive: TuiDropdownPosition, outputs: ["tuiDropdownDirectionChange", "tuiDropdownDirectionChange"] }], ngImport: i0 }); }
364
386
  }
365
387
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownDirective, decorators: [{
366
388
  type: Directive,
367
389
  args: [{
368
390
  selector: '[tuiDropdown]:not(ng-container):not(ng-template)',
369
- providers: [
370
- tuiAsVehicle(TuiDropdownDirective),
371
- tuiProvide(TUI_DROPDOWN_HOST, ElementRef),
372
- ],
391
+ providers: [tuiAsVehicle(TuiDropdownDirective)],
373
392
  exportAs: 'tuiDropdown',
374
393
  hostDirectives: [
394
+ TuiDropdownHost,
375
395
  TuiDropdownDriverDirective,
376
396
  { directive: TuiDropdownA11y, inputs: ['tuiDropdownRole'] },
377
397
  {
@@ -558,6 +578,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
558
578
  args: [{ selector: 'ng-template[tuiDropdown]' }]
559
579
  }], ctorParameters: () => [] });
560
580
 
581
+ const STYLE = {
582
+ position: 'fixed',
583
+ blockSize: '1px',
584
+ inlineSize: '1px',
585
+ pointerEvents: 'none',
586
+ };
561
587
  class TuiDropdownContext extends TuiRectAccessor {
562
588
  constructor() {
563
589
  super(...arguments);
@@ -580,12 +606,27 @@ class TuiDropdownContext extends TuiRectAccessor {
580
606
  this.currentRect = EMPTY_CLIENT_RECT;
581
607
  });
582
608
  this.type = 'dropdown';
609
+ this.nativeElement = this.doc.createElement('div');
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);
617
+ }
618
+ ngOnDestroy() {
619
+ this.nativeElement.parentNode?.removeChild(this.nativeElement);
583
620
  }
584
621
  getClientRect() {
585
622
  return this.currentRect;
586
623
  }
587
624
  onContextMenu(x, y) {
625
+ const { top, left } = this.el.getBoundingClientRect();
588
626
  this.currentRect = tuiPointToClientRect(x, y);
627
+ this.nativeElement.style.top = `calc(anchor(top) + ${y - top}px)`;
628
+ this.nativeElement.style.left = `calc(anchor(left) + ${x - left}px)`;
629
+ this.doc.body.appendChild(this.nativeElement);
589
630
  this.driver.next(true);
590
631
  }
591
632
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownContext, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
@@ -594,6 +635,7 @@ class TuiDropdownContext extends TuiRectAccessor {
594
635
  TuiDropdownDriver,
595
636
  tuiAsDriver(TuiDropdownDriver),
596
637
  tuiAsRectAccessor(TuiDropdownContext),
638
+ tuiProvide(TUI_DROPDOWN_ANCHOR, TuiDropdownContext),
597
639
  ], usesInheritance: true, ngImport: i0 }); }
598
640
  }
599
641
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownContext, decorators: [{
@@ -605,6 +647,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
605
647
  TuiDropdownDriver,
606
648
  tuiAsDriver(TuiDropdownDriver),
607
649
  tuiAsRectAccessor(TuiDropdownContext),
650
+ tuiProvide(TUI_DROPDOWN_ANCHOR, TuiDropdownContext),
608
651
  ],
609
652
  host: {
610
653
  '[style.-webkit-touch-callout]': 'userSelect()',
@@ -802,16 +845,35 @@ class TuiDropdownSelection extends TuiDriver {
802
845
  const contained = this.el.contains(range.commonAncestorContainer);
803
846
  const valid = contained && handler(this.range);
804
847
  const visible = valid || this.inDropdown(range);
805
- const active = tuiGetFocused(this.doc);
806
- const textfield = active && tuiIsTextfield(active) && this.el.contains(active);
848
+ const focus = tuiGetFocused(this.doc);
849
+ const textfield = focus && tuiIsTextfield(focus) && this.el.contains(focus);
850
+ this.updateAnchor();
807
851
  return visible && textfield ? this.isCaretVisible(this.range) : visible;
808
852
  }));
809
853
  this.range = isPlatformBrowser(inject(PLATFORM_ID))
810
854
  ? new Range()
811
855
  : {};
812
856
  this.type = 'dropdown';
857
+ this.nativeElement = this.doc.createElement('div');
813
858
  this.tuiDropdownSelection = input('');
814
859
  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
+ }
872
+ ngOnDestroy() {
873
+ this.nativeElement.parentNode?.removeChild(this.nativeElement);
874
+ if (this.ghost) {
875
+ this.ghostHost.removeChild(this.ghost);
876
+ }
815
877
  }
816
878
  getClientRect() {
817
879
  switch (this.tuiDropdownSelectionPosition()) {
@@ -830,11 +892,6 @@ class TuiDropdownSelection extends TuiDriver {
830
892
  return this.range.getBoundingClientRect();
831
893
  }
832
894
  }
833
- ngOnDestroy() {
834
- if (this.ghost) {
835
- this.ghostHost.removeChild(this.ghost);
836
- }
837
- }
838
895
  get ghostHost() {
839
896
  return this.el.querySelector('tui-textfield .t-ghost') || this.el;
840
897
  }
@@ -917,10 +974,21 @@ class TuiDropdownSelection extends TuiDriver {
917
974
  const threshold = lineHeight * 0.5;
918
975
  return visibleHeight >= threshold;
919
976
  }
977
+ updateAnchor() {
978
+ const rect = this.getClientRect();
979
+ const { top, left } = this.el.getBoundingClientRect();
980
+ Object.assign(this.nativeElement.style, {
981
+ top: `calc(anchor(top) + ${rect.top - top}px)`,
982
+ left: `calc(anchor(left) + ${rect.left - left}px)`,
983
+ blockSize: tuiPx(rect.height),
984
+ inlineSize: tuiPx(rect.width),
985
+ });
986
+ }
920
987
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownSelection, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
921
988
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.25", type: TuiDropdownSelection, isStandalone: true, selector: "[tuiDropdownSelection]", inputs: { tuiDropdownSelection: { classPropertyName: "tuiDropdownSelection", publicName: "tuiDropdownSelection", isSignal: true, isRequired: false, transformFunction: null }, tuiDropdownSelectionPosition: { classPropertyName: "tuiDropdownSelectionPosition", publicName: "tuiDropdownSelectionPosition", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
922
989
  tuiAsDriver(TuiDropdownSelection),
923
990
  tuiAsRectAccessor(TuiDropdownSelection),
991
+ tuiProvide(TUI_DROPDOWN_ANCHOR, TuiDropdownSelection),
924
992
  ], usesInheritance: true, ngImport: i0 }); }
925
993
  }
926
994
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: TuiDropdownSelection, decorators: [{
@@ -930,6 +998,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
930
998
  providers: [
931
999
  tuiAsDriver(TuiDropdownSelection),
932
1000
  tuiAsRectAccessor(TuiDropdownSelection),
1001
+ tuiProvide(TUI_DROPDOWN_ANCHOR, TuiDropdownSelection),
933
1002
  ],
934
1003
  }]
935
1004
  }], ctorParameters: () => [] });
@@ -971,5 +1040,5 @@ const TuiDropdown = [
971
1040
  * Generated bundle index. Do not edit.
972
1041
  */
973
1042
 
974
- export { TUI_DROPDOWN_COMPONENT, TUI_DROPDOWN_CONTEXT, TUI_DROPDOWN_DEFAULT_OPTIONS, TUI_DROPDOWN_HOST, TUI_DROPDOWN_HOVER_DEFAULT_OPTIONS, TUI_DROPDOWN_HOVER_OPTIONS, TUI_DROPDOWN_OPTIONS, TuiDropdown, TuiDropdownA11y, TuiDropdownAnchor, TuiDropdownAuto, TuiDropdownClose, TuiDropdownComponent, TuiDropdownContent, TuiDropdownContext, TuiDropdownDirective, TuiDropdownDriver, TuiDropdownDriverDirective, TuiDropdownFixed, TuiDropdownHover, TuiDropdownManual, TuiDropdownOpen, TuiDropdownOptionsDirective, TuiDropdownPosition, TuiDropdownPositionSided, TuiDropdownSelection, TuiWithDropdownOpen, tuiDropdown, tuiDropdownEnabled, tuiDropdownHoverOptionsProvider, tuiDropdownOptionsProvider };
1043
+ export { TUI_DROPDOWN_ANCHOR, TUI_DROPDOWN_COMPONENT, TUI_DROPDOWN_CONTEXT, TUI_DROPDOWN_DEFAULT_OPTIONS, TUI_DROPDOWN_HOST, TUI_DROPDOWN_HOVER_DEFAULT_OPTIONS, TUI_DROPDOWN_HOVER_OPTIONS, TUI_DROPDOWN_OPTIONS, TuiDropdown, TuiDropdownA11y, TuiDropdownAnchor, TuiDropdownAuto, TuiDropdownClose, TuiDropdownComponent, TuiDropdownContent, TuiDropdownContext, TuiDropdownDirective, TuiDropdownDriver, TuiDropdownDriverDirective, TuiDropdownFixed, TuiDropdownHost, TuiDropdownHover, TuiDropdownManual, TuiDropdownOpen, TuiDropdownOptionsDirective, TuiDropdownPosition, TuiDropdownPositionSided, TuiDropdownSelection, TuiWithDropdownOpen, tuiDropdown, tuiDropdownEnabled, tuiDropdownHoverOptionsProvider, tuiDropdownOptionsProvider };
975
1044
  //# sourceMappingURL=taiga-ui-core-portals-dropdown.mjs.map