@spartan-ng/brain 0.0.1-alpha.380 → 0.0.1-alpha.386

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 (101) hide show
  1. package/accordion/lib/brn-accordion-content.component.d.ts +1 -1
  2. package/accordion/lib/brn-accordion.directive.d.ts +2 -2
  3. package/core/README.md +3 -0
  4. package/core/helpers/create-injection-token.d.ts +20 -0
  5. package/core/helpers/custom-element-class-settable.d.ts +12 -0
  6. package/core/helpers/dev-mode.d.ts +5 -0
  7. package/core/helpers/exposes-side.d.ts +13 -0
  8. package/core/helpers/exposes-state.d.ts +13 -0
  9. package/core/helpers/hlm.d.ts +2 -0
  10. package/core/helpers/table-classes-settable.d.ts +16 -0
  11. package/core/helpers/zone-free.d.ts +10 -0
  12. package/core/index.d.ts +7 -0
  13. package/esm2022/accordion/lib/brn-accordion-content.component.mjs +1 -1
  14. package/esm2022/accordion/lib/brn-accordion.directive.mjs +8 -3
  15. package/esm2022/alert-dialog/lib/brn-alert-dialog-content.directive.mjs +2 -2
  16. package/esm2022/alert-dialog/lib/brn-alert-dialog-overlay.component.mjs +2 -2
  17. package/esm2022/core/helpers/create-injection-token.mjs +15 -0
  18. package/esm2022/core/helpers/custom-element-class-settable.mjs +3 -0
  19. package/esm2022/core/helpers/dev-mode.mjs +6 -0
  20. package/esm2022/core/helpers/exposes-side.mjs +3 -0
  21. package/esm2022/core/helpers/exposes-state.mjs +3 -0
  22. package/esm2022/core/helpers/hlm.mjs +6 -0
  23. package/esm2022/core/helpers/table-classes-settable.mjs +3 -0
  24. package/esm2022/core/helpers/zone-free.mjs +15 -0
  25. package/esm2022/core/index.mjs +8 -0
  26. package/esm2022/core/spartan-ng-brain-core.mjs +5 -0
  27. package/esm2022/dialog/lib/brn-dialog-content.directive.mjs +2 -2
  28. package/esm2022/dialog/lib/brn-dialog-overlay.component.mjs +2 -2
  29. package/esm2022/dialog/lib/brn-dialog-ref.mjs +3 -2
  30. package/esm2022/dialog/lib/brn-dialog.component.mjs +2 -2
  31. package/esm2022/dialog/lib/brn-dialog.service.mjs +3 -2
  32. package/esm2022/hover-card/lib/brn-hover-card-content.service.mjs +26 -36
  33. package/esm2022/hover-card/lib/brn-hover-card.component.mjs +8 -14
  34. package/esm2022/hover-card/lib/createHoverObservable.mjs +4 -3
  35. package/esm2022/menu/lib/brn-menu-trigger.directive.mjs +9 -3
  36. package/esm2022/popover/lib/brn-popover-content.directive.mjs +2 -2
  37. package/esm2022/radio-group/index.mjs +5 -5
  38. package/esm2022/radio-group/lib/{brn-radio-group.component.mjs → brn-radio-group.directive.mjs} +12 -12
  39. package/esm2022/radio-group/lib/brn-radio-group.token.mjs +3 -3
  40. package/esm2022/select/lib/brn-select-content.component.mjs +3 -2
  41. package/esm2022/select/lib/brn-select.component.mjs +4 -3
  42. package/esm2022/select/lib/brn-select.service.mjs +3 -2
  43. package/esm2022/sheet/lib/brn-sheet-content.directive.mjs +2 -2
  44. package/esm2022/sheet/lib/brn-sheet-overlay.component.mjs +2 -2
  45. package/esm2022/slider/lib/brn-slider-track.directive.mjs +3 -2
  46. package/esm2022/table/lib/brn-table.component.mjs +2 -2
  47. package/esm2022/tabs/lib/brn-tabs-list.directive.mjs +3 -2
  48. package/esm2022/toggle/lib/brn-toggle.directive.mjs +3 -3
  49. package/esm2022/tooltip/index.mjs +2 -1
  50. package/esm2022/tooltip/lib/brn-tooltip-content.component.mjs +8 -15
  51. package/esm2022/tooltip/lib/brn-tooltip-trigger.directive.mjs +136 -200
  52. package/esm2022/tooltip/lib/brn-tooltip.token.mjs +18 -0
  53. package/esm2022/tooltip/lib/computed-previous.mjs +46 -0
  54. package/fesm2022/spartan-ng-brain-accordion.mjs +7 -2
  55. package/fesm2022/spartan-ng-brain-accordion.mjs.map +1 -1
  56. package/fesm2022/spartan-ng-brain-alert-dialog.mjs +1 -1
  57. package/fesm2022/spartan-ng-brain-alert-dialog.mjs.map +1 -1
  58. package/fesm2022/spartan-ng-brain-core.mjs +57 -0
  59. package/fesm2022/spartan-ng-brain-core.mjs.map +1 -0
  60. package/fesm2022/spartan-ng-brain-dialog.mjs +3 -2
  61. package/fesm2022/spartan-ng-brain-dialog.mjs.map +1 -1
  62. package/fesm2022/spartan-ng-brain-hover-card.mjs +31 -40
  63. package/fesm2022/spartan-ng-brain-hover-card.mjs.map +1 -1
  64. package/fesm2022/spartan-ng-brain-menu.mjs +8 -2
  65. package/fesm2022/spartan-ng-brain-menu.mjs.map +1 -1
  66. package/fesm2022/spartan-ng-brain-popover.mjs +1 -1
  67. package/fesm2022/spartan-ng-brain-popover.mjs.map +1 -1
  68. package/fesm2022/spartan-ng-brain-radio-group.mjs +16 -16
  69. package/fesm2022/spartan-ng-brain-radio-group.mjs.map +1 -1
  70. package/fesm2022/spartan-ng-brain-select.mjs +3 -2
  71. package/fesm2022/spartan-ng-brain-select.mjs.map +1 -1
  72. package/fesm2022/spartan-ng-brain-sheet.mjs +1 -1
  73. package/fesm2022/spartan-ng-brain-sheet.mjs.map +1 -1
  74. package/fesm2022/spartan-ng-brain-slider.mjs +2 -1
  75. package/fesm2022/spartan-ng-brain-slider.mjs.map +1 -1
  76. package/fesm2022/spartan-ng-brain-table.mjs +1 -1
  77. package/fesm2022/spartan-ng-brain-table.mjs.map +1 -1
  78. package/fesm2022/spartan-ng-brain-tabs.mjs +2 -2
  79. package/fesm2022/spartan-ng-brain-tabs.mjs.map +1 -1
  80. package/fesm2022/spartan-ng-brain-toggle.mjs +2 -2
  81. package/fesm2022/spartan-ng-brain-toggle.mjs.map +1 -1
  82. package/fesm2022/spartan-ng-brain-tooltip.mjs +200 -211
  83. package/fesm2022/spartan-ng-brain-tooltip.mjs.map +1 -1
  84. package/hlm-tailwind-preset.js +73 -0
  85. package/hover-card/lib/brn-hover-card-content.service.d.ts +18 -11
  86. package/hover-card/lib/brn-hover-card.component.d.ts +2 -2
  87. package/hover-card/lib/createHoverObservable.d.ts +1 -1
  88. package/menu/lib/brn-menu-trigger.directive.d.ts +1 -1
  89. package/package.json +57 -46
  90. package/radio-group/index.d.ts +5 -5
  91. package/radio-group/lib/{brn-radio-group.component.d.ts → brn-radio-group.directive.d.ts} +3 -3
  92. package/radio-group/lib/brn-radio-group.token.d.ts +3 -3
  93. package/radio-group/lib/brn-radio.component.d.ts +1 -1
  94. package/select/lib/brn-select.component.d.ts +1 -1
  95. package/sheet/lib/brn-sheet-content.directive.d.ts +1 -1
  96. package/table/lib/brn-table.component.d.ts +1 -1
  97. package/tooltip/index.d.ts +1 -0
  98. package/tooltip/lib/brn-tooltip-content.component.d.ts +2 -2
  99. package/tooltip/lib/brn-tooltip-trigger.directive.d.ts +24 -64
  100. package/tooltip/lib/brn-tooltip.token.d.ts +28 -0
  101. package/tooltip/lib/computed-previous.d.ts +36 -0
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ChangeDetectorRef, PLATFORM_ID, Renderer2, signal, Component, ViewEncapsulation, ChangeDetectionStrategy, ViewChild, Directive, TemplateRef, InjectionToken, ElementRef, ViewContainerRef, NgZone, effect, isDevMode, booleanAttribute, numberAttribute, Input, NgModule } from '@angular/core';
2
+ import { inject, ChangeDetectorRef, PLATFORM_ID, Renderer2, signal, viewChild, ElementRef, Component, ViewEncapsulation, ChangeDetectionStrategy, Directive, TemplateRef, InjectionToken, untracked, computed, ViewContainerRef, NgZone, input, booleanAttribute, numberAttribute, effect, isDevMode, NgModule } from '@angular/core';
3
3
  import { isPlatformBrowser, NgTemplateOutlet, DOCUMENT } from '@angular/common';
4
4
  import { Subject } from 'rxjs';
5
5
  import { AriaDescriber, FocusMonitor } from '@angular/cdk/a11y';
@@ -8,7 +8,7 @@ import { hasModifierKey } from '@angular/cdk/keycodes';
8
8
  import { Overlay, ScrollDispatcher } from '@angular/cdk/overlay';
9
9
  import { normalizePassiveListenerOptions, Platform } from '@angular/cdk/platform';
10
10
  import { ComponentPortal } from '@angular/cdk/portal';
11
- import { brnDevMode } from '@spartan-ng/ui-core';
11
+ import { brnDevMode } from '@spartan-ng/brain/core';
12
12
  import { takeUntil, take } from 'rxjs/operators';
13
13
 
14
14
  /**
@@ -42,7 +42,7 @@ class BrnTooltipContentComponent {
42
42
  /** Amount of milliseconds of closing animation. */
43
43
  _exitAnimationDuration = 0;
44
44
  /** Reference to the internal tooltip element. */
45
- _tooltip;
45
+ _tooltip = viewChild('tooltip', { read: (ElementRef) });
46
46
  /** Whether interactions on the page should close the tooltip */
47
47
  _closeOnInteraction = false;
48
48
  /** Whether the tooltip is currently visible. */
@@ -156,7 +156,7 @@ class BrnTooltipContentComponent {
156
156
  // We set the classes directly here ourselves so that toggling the tooltip state
157
157
  // isn't bound by change detection. This allows us to hide it even if the
158
158
  // view ref has been detached from the CD tree.
159
- const tooltip = this._tooltip?.nativeElement;
159
+ const tooltip = this._tooltip()?.nativeElement;
160
160
  if (!tooltip || !this._isBrowser)
161
161
  return;
162
162
  this._renderer2.setStyle(tooltip, 'visibility', isVisible ? 'visible' : 'hidden');
@@ -172,14 +172,14 @@ class BrnTooltipContentComponent {
172
172
  // We set the classes directly here ourselves so that toggling the tooltip state
173
173
  // isn't bound by change detection. This allows us to hide it even if the
174
174
  // view ref has been detached from the CD tree.
175
- const tooltip = this._tooltip?.nativeElement;
175
+ const tooltip = this._tooltip()?.nativeElement;
176
176
  if (!tooltip || !this._isBrowser)
177
177
  return;
178
178
  this._renderer2.setAttribute(tooltip, 'data-side', side);
179
179
  this._renderer2.setAttribute(tooltip, 'data-state', isVisible ? 'open' : 'closed');
180
180
  }
181
181
  /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: BrnTooltipContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
182
- /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.5", type: BrnTooltipContentComponent, isStandalone: true, selector: "brn-tooltip-content", host: { attributes: { "aria-hidden": "true" }, listeners: { "mouseleave": "_handleMouseLeave($event)" }, properties: { "style.zoom": "isVisible() ? 1 : null" } }, viewQueries: [{ propertyName: "_tooltip", first: true, predicate: ["tooltip"], descendants: true, static: true }], ngImport: i0, template: `
182
+ /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.5", type: BrnTooltipContentComponent, isStandalone: true, selector: "brn-tooltip-content", host: { attributes: { "aria-hidden": "true" }, listeners: { "mouseleave": "_handleMouseLeave($event)" }, properties: { "style.zoom": "isVisible() ? 1 : null" } }, viewQueries: [{ propertyName: "_tooltip", first: true, predicate: ["tooltip"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: `
183
183
  <div
184
184
  (mouseenter)="_contentHovered.set(true)"
185
185
  (mouseleave)="_contentHovered.set(false)"
@@ -226,14 +226,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImpor
226
226
  },
227
227
  imports: [NgTemplateOutlet],
228
228
  }]
229
- }], propDecorators: { _tooltip: [{
230
- type: ViewChild,
231
- args: ['tooltip', {
232
- // Use a static query here since we interact directly with
233
- // the DOM which can happen before `ngAfterViewInit`.
234
- static: true,
235
- }]
236
- }] } });
229
+ }] });
237
230
 
238
231
  class BrnTooltipDirective {
239
232
  tooltipTemplate = signal(null);
@@ -267,6 +260,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImpor
267
260
  }]
268
261
  }], ctorParameters: () => [] });
269
262
 
263
+ const defaultOptions = {
264
+ showDelay: 0,
265
+ hideDelay: 0,
266
+ exitAnimationDuration: 0,
267
+ touchendHideDelay: 1500,
268
+ };
269
+ const BRN_TOOLTIP_DEFAULT_OPTIONS = new InjectionToken('brn-tooltip-default-options', {
270
+ providedIn: 'root',
271
+ factory: () => defaultOptions,
272
+ });
273
+ function provideBrnTooltipDefaultOptions(options) {
274
+ return { provide: BRN_TOOLTIP_DEFAULT_OPTIONS, useValue: { ...defaultOptions, ...options } };
275
+ }
276
+ function injectBrnTooltipDefaultOptions() {
277
+ return inject(BRN_TOOLTIP_DEFAULT_OPTIONS, { optional: true }) ?? defaultOptions;
278
+ }
279
+
280
+ /**
281
+ * Returns a signal that emits the previous value of the given signal.
282
+ * The first time the signal is emitted, the previous value will be the same as the current value.
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * const value = signal(0);
287
+ * const previous = computedPrevious(value);
288
+ *
289
+ * effect(() => {
290
+ * console.log('Current value:', value());
291
+ * console.log('Previous value:', previous());
292
+ * });
293
+ *
294
+ * Logs:
295
+ * // Current value: 0
296
+ * // Previous value: 0
297
+ *
298
+ * value.set(1);
299
+ *
300
+ * Logs:
301
+ * // Current value: 1
302
+ * // Previous value: 0
303
+ *
304
+ * value.set(2);
305
+ *
306
+ * Logs:
307
+ * // Current value: 2
308
+ * // Previous value: 1
309
+ *```
310
+ *
311
+ * @param computation Signal to compute previous value for
312
+ * @returns Signal that emits previous value of `s`
313
+ */
314
+ function computedPrevious(computation) {
315
+ let current = null;
316
+ let previous = untracked(() => computation()); // initial value is the current value
317
+ return computed(() => {
318
+ current = computation();
319
+ const result = previous;
320
+ previous = current;
321
+ return result;
322
+ });
323
+ }
324
+
270
325
  /**
271
326
  * We are building on shoulders of giants here and adapt the implementation provided by the incredible Angular
272
327
  * team: https://github.com/angular/components/blob/main/src/material/tooltip/tooltip.ts
@@ -291,17 +346,6 @@ const BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER = {
291
346
  deps: [Overlay],
292
347
  useFactory: (overlay) => () => overlay.scrollStrategies.reposition({ scrollThrottle: SCROLL_THROTTLE_MS }),
293
348
  };
294
- function BRN_TOOLTIP_DEFAULT_OPTIONS_FACTORY() {
295
- return {
296
- showDelay: 0,
297
- hideDelay: 0,
298
- touchendHideDelay: 1500,
299
- };
300
- }
301
- const BRN_TOOLTIP_DEFAULT_OPTIONS = new InjectionToken('mat-tooltip-default-options', {
302
- providedIn: 'root',
303
- factory: BRN_TOOLTIP_DEFAULT_OPTIONS_FACTORY,
304
- });
305
349
  const PANEL_CLASS = 'tooltip-panel';
306
350
  /** Options used to bind passive event listeners. */
307
351
  const passiveListenerOptions = normalizePassiveListenerOptions({ passive: true });
@@ -319,7 +363,7 @@ class BrnTooltipTriggerDirective {
319
363
  _cssClassPrefix = 'brn';
320
364
  _destroyed = new Subject();
321
365
  _passiveListeners = [];
322
- _defaultOptions = inject(BRN_TOOLTIP_DEFAULT_OPTIONS, { optional: true });
366
+ _defaultOptions = injectBrnTooltipDefaultOptions();
323
367
  _overlay = inject(Overlay);
324
368
  _elementRef = inject((ElementRef));
325
369
  _scrollDispatcher = inject(ScrollDispatcher);
@@ -340,89 +384,26 @@ class BrnTooltipTriggerDirective {
340
384
  _overlayRef = null;
341
385
  _tooltipInstance = null;
342
386
  /** Allows the user to define the position of the tooltip relative to the parent element */
343
- _position = signal('above');
344
- get position() {
345
- return this._position();
346
- }
347
- set position(value) {
348
- if (value !== this._position()) {
349
- this._position.set(value);
350
- if (this._overlayRef) {
351
- this._updatePosition(this._overlayRef);
352
- this._tooltipInstance?.show(0);
353
- this._overlayRef.updatePosition();
354
- }
355
- }
356
- }
387
+ position = input(this._defaultOptions?.position ?? 'above');
357
388
  /**
358
389
  * Whether tooltip should be relative to the click or touch origin
359
390
  * instead of outside the element bounding box.
360
391
  */
361
- _positionAtOrigin = signal(false);
362
- get positionAtOrigin() {
363
- return this._positionAtOrigin();
364
- }
365
- set positionAtOrigin(value) {
366
- this._positionAtOrigin.set(value);
367
- this._detach();
368
- this._overlayRef = null;
369
- }
392
+ positionAtOrigin = input(this._defaultOptions?.positionAtOrigin ?? false, {
393
+ transform: booleanAttribute,
394
+ });
370
395
  /** Disables the display of the tooltip. */
371
- _disabled = signal(false);
372
- get disabled() {
373
- return this._disabled();
374
- }
375
- set disabled(value) {
376
- this._disabled.set(value);
377
- // If tooltip is disabled, hide immediately.
378
- if (value) {
379
- this.hide(0);
380
- }
381
- else {
382
- this._setupPointerEnterEventsIfNeeded();
383
- }
384
- }
396
+ brnTooltipDisabled = input(false, { transform: booleanAttribute });
385
397
  /** The default delay in ms before showing the tooltip after show is called */
386
- _showDelay = signal(0);
387
- get showDelay() {
388
- return this._showDelay();
389
- }
390
- set showDelay(value) {
391
- this._showDelay.set(value);
392
- }
398
+ showDelay = input(this._defaultOptions?.showDelay ?? 0, { transform: numberAttribute });
393
399
  /** The default delay in ms before hiding the tooltip after hide is called */
394
- _hideDelay = signal(0);
395
- get hideDelay() {
396
- return this._hideDelay();
397
- }
398
- set hideDelay(value) {
399
- this._hideDelay.set(value);
400
- if (this._tooltipInstance) {
401
- this._tooltipInstance._mouseLeaveHideDelay = this._hideDelay();
402
- }
403
- }
400
+ hideDelay = input(this._defaultOptions?.hideDelay ?? 0, { transform: numberAttribute });
404
401
  /** The default duration in ms that exit animation takes before hiding */
405
- _exitAnimationDuration = signal(0);
406
- get exitAnimationDuration() {
407
- return this._exitAnimationDuration();
408
- }
409
- set exitAnimationDuration(value) {
410
- this._exitAnimationDuration.set(value);
411
- if (this._tooltipInstance) {
412
- this._tooltipInstance._exitAnimationDuration = this._exitAnimationDuration();
413
- }
414
- }
402
+ exitAnimationDuration = input(this._defaultOptions?.exitAnimationDuration ?? 0, {
403
+ transform: numberAttribute,
404
+ });
415
405
  /** The default delay in ms before hiding the tooltip after hide is called */
416
- _tooltipContentClasses = signal('');
417
- get tooltipContentClasses() {
418
- return this._tooltipContentClasses();
419
- }
420
- set tooltipContentClasses(value) {
421
- this._tooltipContentClasses.set(value ?? '');
422
- if (this._tooltipInstance) {
423
- this._tooltipInstance._tooltipClasses.set(value ?? '');
424
- }
425
- }
406
+ tooltipContentClasses = input(this._defaultOptions?.tooltipContentClasses ?? '');
426
407
  /**
427
408
  * How touch gestures should be handled by the tooltip. On touch devices the tooltip directive
428
409
  * uses a long press gesture to show and hide, however it can conflict with the native browser
@@ -437,78 +418,110 @@ class BrnTooltipTriggerDirective {
437
418
  * - `off` - Disables touch gestures. Note that this will prevent the tooltip from
438
419
  * showing on touch devices.
439
420
  */
440
- _touchGestures = signal('auto');
441
- set touchGestures(value) {
442
- this._touchGestures.set(value);
443
- }
444
- get touchGestures() {
445
- return this._touchGestures();
446
- }
421
+ touchGestures = input(this._defaultOptions?.touchGestures ?? 'auto');
447
422
  /** The message to be used to describe the aria in the tooltip */
448
- _ariaDescribedBy = '';
449
- get ariaDescribedBy() {
450
- return this._ariaDescribedBy;
451
- }
452
- set ariaDescribedBy(value) {
453
- this._ariaDescriber.removeDescription(this._elementRef.nativeElement, this._ariaDescribedBy, 'tooltip');
454
- // If the message is not a string (e.g. number), convert it to a string and trim it.
455
- // Must convert with `String(value)`, not `${value}`, otherwise Closure Compiler optimises
456
- // away the string-conversion: https://github.com/angular/components/issues/20684
457
- this._ariaDescribedBy = value !== null ? String(value).trim() : '';
458
- if (this._ariaDescribedBy && !this._isTooltipVisible()) {
459
- this._ngZone.runOutsideAngular(() => {
460
- // The `AriaDescriber` has some functionality that avoids adding a description if it's the
461
- // same as the `aria-label` of an element, however we can't know whether the tooltip trigger
462
- // has a data-bound `aria-label` or when it'll be set for the first time. We can avoid the
463
- // issue by deferring the description by a tick so Angular has time to set the `aria-label`.
464
- Promise.resolve().then(() => {
465
- this._ariaDescriber.describe(this._elementRef.nativeElement, this._ariaDescribedBy, 'tooltip');
466
- });
467
- });
468
- }
469
- }
423
+ ariaDescribedBy = input('', { alias: 'aria-describedby' });
424
+ ariaDescribedByPrevious = computedPrevious(this.ariaDescribedBy);
470
425
  /** The content to be displayed in the tooltip */
471
- _content = null;
472
- get content() {
473
- return this._content;
474
- }
475
- set content(value) {
476
- this._content = value;
477
- if (!this._content && this._isTooltipVisible()) {
478
- this.hide(0);
479
- }
480
- else {
481
- this._setupPointerEnterEventsIfNeeded();
482
- this._updateTooltipContent();
426
+ brnTooltipTrigger = input(null);
427
+ brnTooltipTriggerState = computed(() => {
428
+ if (this._tooltipDirective) {
429
+ return this._tooltipDirective.tooltipTemplate();
483
430
  }
484
- }
431
+ return this.brnTooltipTrigger();
432
+ });
485
433
  constructor() {
486
- if (this._defaultOptions) {
487
- this._showDelay.set(this._defaultOptions.showDelay);
488
- this._hideDelay.set(this._defaultOptions.hideDelay);
489
- if (this._defaultOptions.position) {
490
- this.position = this._defaultOptions.position;
491
- }
492
- if (this._defaultOptions.positionAtOrigin) {
493
- this.positionAtOrigin = this._defaultOptions.positionAtOrigin;
494
- }
495
- if (this._defaultOptions.touchGestures) {
496
- this.touchGestures = this._defaultOptions.touchGestures;
497
- }
498
- }
499
434
  this._dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
500
435
  if (this._overlayRef) {
501
436
  this._updatePosition(this._overlayRef);
502
437
  }
503
438
  });
504
439
  this._viewportMargin = MIN_VIEWPORT_TOOLTIP_THRESHOLD;
505
- if (this._tooltipDirective) {
506
- effect(() => {
507
- if (this._tooltipDirective) {
508
- this.content = this._tooltipDirective.tooltipTemplate();
509
- }
510
- });
511
- }
440
+ this._initBrnTooltipTriggerEffect();
441
+ this._initAriaDescribedByPreviousEffect();
442
+ this._initTooltipContentClassesEffect();
443
+ this._initPositionEffect();
444
+ this._initPositionAtOriginEffect();
445
+ this._initBrnTooltipDisabledEffect();
446
+ this._initExitAnimationDurationEffect();
447
+ this._initHideDelayEffect();
448
+ }
449
+ _initPositionEffect() {
450
+ effect(() => {
451
+ if (this._overlayRef) {
452
+ this._updatePosition(this._overlayRef);
453
+ this._tooltipInstance?.show(0);
454
+ this._overlayRef.updatePosition();
455
+ }
456
+ });
457
+ }
458
+ _initBrnTooltipDisabledEffect() {
459
+ effect(() => {
460
+ if (this.brnTooltipDisabled()) {
461
+ this.hide(0);
462
+ }
463
+ else {
464
+ this._setupPointerEnterEventsIfNeeded();
465
+ }
466
+ });
467
+ }
468
+ _initPositionAtOriginEffect() {
469
+ effect(() => {
470
+ // Needed that the effect got triggered
471
+ // eslint-disable-next-line @typescript-eslint/naming-convention
472
+ const _ = this.positionAtOrigin();
473
+ this._detach();
474
+ this._overlayRef = null;
475
+ });
476
+ }
477
+ _initTooltipContentClassesEffect() {
478
+ effect(() => {
479
+ if (this._tooltipInstance) {
480
+ this._tooltipInstance._tooltipClasses.set(this.tooltipContentClasses() ?? '');
481
+ }
482
+ });
483
+ }
484
+ _initAriaDescribedByPreviousEffect() {
485
+ effect(() => {
486
+ const ariaDescribedBy = this.ariaDescribedBy();
487
+ this._ariaDescriber.removeDescription(this._elementRef.nativeElement, untracked(() => this.ariaDescribedByPrevious()), 'tooltip');
488
+ if (ariaDescribedBy && !this._isTooltipVisible()) {
489
+ this._ngZone.runOutsideAngular(() => {
490
+ // The `AriaDescriber` has some functionality that avoids adding a description if it's the
491
+ // same as the `aria-label` of an element, however we can't know whether the tooltip trigger
492
+ // has a data-bound `aria-label` or when it'll be set for the first time. We can avoid the
493
+ // issue by deferring the description by a tick so Angular has time to set the `aria-label`.
494
+ Promise.resolve().then(() => {
495
+ this._ariaDescriber.describe(this._elementRef.nativeElement, ariaDescribedBy, 'tooltip');
496
+ });
497
+ });
498
+ }
499
+ });
500
+ }
501
+ _initBrnTooltipTriggerEffect() {
502
+ effect(() => {
503
+ if (!this.brnTooltipTriggerState() && this._isTooltipVisible()) {
504
+ this.hide(0);
505
+ }
506
+ else {
507
+ this._setupPointerEnterEventsIfNeeded();
508
+ this._updateTooltipContent();
509
+ }
510
+ }, { allowSignalWrites: true });
511
+ }
512
+ _initExitAnimationDurationEffect() {
513
+ effect(() => {
514
+ if (this._tooltipInstance) {
515
+ this._tooltipInstance._exitAnimationDuration = this.exitAnimationDuration();
516
+ }
517
+ });
518
+ }
519
+ _initHideDelayEffect() {
520
+ effect(() => {
521
+ if (this._tooltipInstance) {
522
+ this._tooltipInstance._mouseLeaveHideDelay = this.hideDelay();
523
+ }
524
+ });
512
525
  }
513
526
  ngAfterViewInit() {
514
527
  // This needs to happen after view init so the initial values for all inputs have been set.
@@ -526,7 +539,7 @@ class BrnTooltipTriggerDirective {
526
539
  this._ngZone.run(() => this.show());
527
540
  }
528
541
  });
529
- if (brnDevMode && !this._ariaDescribedBy) {
542
+ if (brnDevMode && !this.ariaDescribedBy()) {
530
543
  console.warn('BrnTooltip: "aria-describedby" attribute is required for accessibility');
531
544
  }
532
545
  }
@@ -545,12 +558,12 @@ class BrnTooltipTriggerDirective {
545
558
  this._passiveListeners.length = 0;
546
559
  this._destroyed.next();
547
560
  this._destroyed.complete();
548
- this._ariaDescriber.removeDescription(nativeElement, this._ariaDescribedBy, 'tooltip');
561
+ this._ariaDescriber.removeDescription(nativeElement, this.ariaDescribedBy(), 'tooltip');
549
562
  this._focusMonitor.stopMonitoring(nativeElement);
550
563
  }
551
564
  /** Shows the tooltip after the delay in ms, defaults to tooltip-delay-show or 0ms if no input */
552
- show(delay = this.showDelay, origin) {
553
- if (this.disabled || this._isTooltipVisible()) {
565
+ show(delay = this.showDelay(), origin) {
566
+ if (this.brnTooltipDisabled() || this._isTooltipVisible()) {
554
567
  this._tooltipInstance?._cancelPendingAnimations();
555
568
  return;
556
569
  }
@@ -559,16 +572,16 @@ class BrnTooltipTriggerDirective {
559
572
  this._portal = this._portal || new ComponentPortal(this._tooltipComponent, this._viewContainerRef);
560
573
  const instance = (this._tooltipInstance = overlayRef.attach(this._portal).instance);
561
574
  instance._triggerElement = this._elementRef.nativeElement;
562
- instance._mouseLeaveHideDelay = this._hideDelay();
563
- instance._tooltipClasses.set(this._tooltipContentClasses());
564
- instance._exitAnimationDuration = this._exitAnimationDuration();
575
+ instance._mouseLeaveHideDelay = this.hideDelay();
576
+ instance._tooltipClasses.set(this.tooltipContentClasses());
577
+ instance._exitAnimationDuration = this.exitAnimationDuration();
565
578
  instance.side.set(this._currentPosition ?? 'above');
566
579
  instance.afterHidden.pipe(takeUntil(this._destroyed)).subscribe(() => this._detach());
567
580
  this._updateTooltipContent();
568
581
  instance.show(delay);
569
582
  }
570
583
  /** Hides the tooltip after the delay in ms, defaults to tooltip-delay-hide or 0ms if no input */
571
- hide(delay = this.hideDelay, exitAnimationDuration = this.exitAnimationDuration) {
584
+ hide(delay = this.hideDelay(), exitAnimationDuration = this.exitAnimationDuration()) {
572
585
  const instance = this._tooltipInstance;
573
586
  if (instance) {
574
587
  if (instance.isVisible()) {
@@ -589,7 +602,7 @@ class BrnTooltipTriggerDirective {
589
602
  _createOverlay(origin) {
590
603
  if (this._overlayRef) {
591
604
  const existingStrategy = this._overlayRef.getConfig().positionStrategy;
592
- if ((!this.positionAtOrigin || !origin) && existingStrategy._origin instanceof ElementRef) {
605
+ if ((!this.positionAtOrigin() || !origin) && existingStrategy._origin instanceof ElementRef) {
593
606
  return this._overlayRef;
594
607
  }
595
608
  this._detach();
@@ -598,7 +611,7 @@ class BrnTooltipTriggerDirective {
598
611
  // Create connected position strategy that listens for scroll events to reposition.
599
612
  const strategy = this._overlay
600
613
  .position()
601
- .flexibleConnectedTo(this.positionAtOrigin ? origin || this._elementRef : this._elementRef)
614
+ .flexibleConnectedTo(this.positionAtOrigin() ? origin || this._elementRef : this._elementRef)
602
615
  .withTransformOriginOn(`.${this._cssClassPrefix}-tooltip`)
603
616
  .withFlexibleDimensions(false)
604
617
  .withViewportMargin(this._viewportMargin)
@@ -682,7 +695,7 @@ class BrnTooltipTriggerDirective {
682
695
  */
683
696
  _getOrigin() {
684
697
  const isLtr = !this._dir || this._dir.value === 'ltr';
685
- const position = this.position;
698
+ const position = this.position();
686
699
  let originPosition;
687
700
  if (position === 'above' || position === 'below') {
688
701
  originPosition = { originX: 'center', originY: position === 'above' ? 'top' : 'bottom' };
@@ -705,7 +718,7 @@ class BrnTooltipTriggerDirective {
705
718
  /** Returns the overlay position and a fallback position based on the user's preference */
706
719
  _getOverlayPosition() {
707
720
  const isLtr = !this._dir || this._dir.value === 'ltr';
708
- const position = this.position;
721
+ const position = this.position();
709
722
  let overlayPosition;
710
723
  if (position === 'above') {
711
724
  overlayPosition = { overlayX: 'center', overlayY: 'bottom' };
@@ -733,7 +746,7 @@ class BrnTooltipTriggerDirective {
733
746
  // Must wait for the template to be painted to the tooltip so that the overlay can properly
734
747
  // calculate the correct positioning based on the size of the tek-pate.
735
748
  if (this._tooltipInstance) {
736
- this._tooltipInstance.content = this.content;
749
+ this._tooltipInstance.content = this.brnTooltipTriggerState();
737
750
  this._tooltipInstance._markForCheck();
738
751
  this._ngZone.onMicrotaskEmpty.pipe(take(1), takeUntil(this._destroyed)).subscribe(() => {
739
752
  if (this._tooltipInstance) {
@@ -744,7 +757,7 @@ class BrnTooltipTriggerDirective {
744
757
  }
745
758
  /** Inverts an overlay position. */
746
759
  _invertPosition(x, y) {
747
- if (this.position === 'above' || this.position === 'below') {
760
+ if (this.position() === 'above' || this.position() === 'below') {
748
761
  if (y === 'top') {
749
762
  y = 'bottom';
750
763
  }
@@ -790,7 +803,10 @@ class BrnTooltipTriggerDirective {
790
803
  /** Binds the pointer events to the tooltip trigger. */
791
804
  _setupPointerEnterEventsIfNeeded() {
792
805
  // Optimization: Defer hooking up events if there's no content or the tooltip is disabled.
793
- if (this._disabled() || !this.content || !this._viewInitialized || this._passiveListeners.length) {
806
+ if (this.brnTooltipDisabled() ||
807
+ !this.brnTooltipTriggerState() ||
808
+ !this._viewInitialized ||
809
+ this._passiveListeners.length) {
794
810
  return;
795
811
  }
796
812
  // The mouse events shouldn't be bound on mobile devices, because they can prevent the
@@ -808,7 +824,7 @@ class BrnTooltipTriggerDirective {
808
824
  },
809
825
  ]);
810
826
  }
811
- else if (this.touchGestures !== 'off') {
827
+ else if (this.touchGestures() !== 'off') {
812
828
  this._disableNativeGesturesIfNecessary();
813
829
  this._passiveListeners.push([
814
830
  'touchstart',
@@ -842,7 +858,7 @@ class BrnTooltipTriggerDirective {
842
858
  },
843
859
  ], ['wheel', (event) => this._wheelListener(event)]);
844
860
  }
845
- else if (this.touchGestures !== 'off') {
861
+ else if (this.touchGestures() !== 'off') {
846
862
  this._disableNativeGesturesIfNecessary();
847
863
  const touchendListener = () => {
848
864
  clearTimeout(this._touchstartTimeout);
@@ -877,7 +893,7 @@ class BrnTooltipTriggerDirective {
877
893
  }
878
894
  /** Disables the native browser gestures, based on how the tooltip has been configured. */
879
895
  _disableNativeGesturesIfNecessary() {
880
- const gestures = this.touchGestures;
896
+ const gestures = this.touchGestures();
881
897
  if (gestures !== 'off') {
882
898
  const element = this._elementRef.nativeElement;
883
899
  const style = element.style;
@@ -899,7 +915,7 @@ class BrnTooltipTriggerDirective {
899
915
  }
900
916
  }
901
917
  /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: BrnTooltipTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
902
- /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.5", type: BrnTooltipTriggerDirective, isStandalone: true, selector: "[brnTooltipTrigger]", inputs: { position: "position", positionAtOrigin: ["positionAtOrigin", "positionAtOrigin", booleanAttribute], disabled: ["brnTooltipDisabled", "disabled", booleanAttribute], showDelay: ["showDelay", "showDelay", numberAttribute], hideDelay: ["hideDelay", "hideDelay", numberAttribute], exitAnimationDuration: ["exitAnimationDuration", "exitAnimationDuration", numberAttribute], tooltipContentClasses: "tooltipContentClasses", touchGestures: "touchGestures", ariaDescribedBy: ["aria-describedby", "ariaDescribedBy"], content: ["brnTooltipTrigger", "content"] }, host: { properties: { "class.brn-tooltip-disabled": "disabled" }, classAttribute: "brn-tooltip-trigger" }, providers: [BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER], exportAs: ["brnTooltipTrigger"], ngImport: i0 });
918
+ /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.5", type: BrnTooltipTriggerDirective, isStandalone: true, selector: "[brnTooltipTrigger]", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, positionAtOrigin: { classPropertyName: "positionAtOrigin", publicName: "positionAtOrigin", isSignal: true, isRequired: false, transformFunction: null }, brnTooltipDisabled: { classPropertyName: "brnTooltipDisabled", publicName: "brnTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "showDelay", isSignal: true, isRequired: false, transformFunction: null }, hideDelay: { classPropertyName: "hideDelay", publicName: "hideDelay", isSignal: true, isRequired: false, transformFunction: null }, exitAnimationDuration: { classPropertyName: "exitAnimationDuration", publicName: "exitAnimationDuration", isSignal: true, isRequired: false, transformFunction: null }, tooltipContentClasses: { classPropertyName: "tooltipContentClasses", publicName: "tooltipContentClasses", isSignal: true, isRequired: false, transformFunction: null }, touchGestures: { classPropertyName: "touchGestures", publicName: "touchGestures", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, brnTooltipTrigger: { classPropertyName: "brnTooltipTrigger", publicName: "brnTooltipTrigger", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.brn-tooltip-disabled": "brnTooltipDisabled()" }, classAttribute: "brn-tooltip-trigger" }, providers: [BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER], exportAs: ["brnTooltipTrigger"], ngImport: i0 });
903
919
  }
904
920
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: BrnTooltipTriggerDirective, decorators: [{
905
921
  type: Directive,
@@ -910,37 +926,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImpor
910
926
  providers: [BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER],
911
927
  host: {
912
928
  class: 'brn-tooltip-trigger',
913
- '[class.brn-tooltip-disabled]': 'disabled',
929
+ '[class.brn-tooltip-disabled]': 'brnTooltipDisabled()',
914
930
  },
915
931
  }]
916
- }], ctorParameters: () => [], propDecorators: { position: [{
917
- type: Input
918
- }], positionAtOrigin: [{
919
- type: Input,
920
- args: [{ transform: booleanAttribute }]
921
- }], disabled: [{
922
- type: Input,
923
- args: [{ transform: booleanAttribute, alias: 'brnTooltipDisabled' }]
924
- }], showDelay: [{
925
- type: Input,
926
- args: [{ transform: numberAttribute }]
927
- }], hideDelay: [{
928
- type: Input,
929
- args: [{ transform: numberAttribute }]
930
- }], exitAnimationDuration: [{
931
- type: Input,
932
- args: [{ transform: numberAttribute }]
933
- }], tooltipContentClasses: [{
934
- type: Input
935
- }], touchGestures: [{
936
- type: Input
937
- }], ariaDescribedBy: [{
938
- type: Input,
939
- args: ['aria-describedby']
940
- }], content: [{
941
- type: Input,
942
- args: ['brnTooltipTrigger']
943
- }] } });
932
+ }], ctorParameters: () => [] });
944
933
 
945
934
  const BrnTooltipImports = [
946
935
  BrnTooltipDirective,
@@ -971,5 +960,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImpor
971
960
  * Generated bundle index. Do not edit.
972
961
  */
973
962
 
974
- export { BRN_TOOLTIP_DEFAULT_OPTIONS, BRN_TOOLTIP_DEFAULT_OPTIONS_FACTORY, BRN_TOOLTIP_SCROLL_STRATEGY, BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER, BrnTooltipContentComponent, BrnTooltipContentDirective, BrnTooltipDirective, BrnTooltipImports, BrnTooltipModule, BrnTooltipTriggerDirective, SCROLL_THROTTLE_MS, getBrnTooltipInvalidPositionError };
963
+ export { BRN_TOOLTIP_SCROLL_STRATEGY, BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER, BrnTooltipContentComponent, BrnTooltipContentDirective, BrnTooltipDirective, BrnTooltipImports, BrnTooltipModule, BrnTooltipTriggerDirective, SCROLL_THROTTLE_MS, defaultOptions, getBrnTooltipInvalidPositionError, injectBrnTooltipDefaultOptions, provideBrnTooltipDefaultOptions };
975
964
  //# sourceMappingURL=spartan-ng-brain-tooltip.mjs.map