ng-hub-ui-utils 22.19.0 → 22.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -385,7 +385,8 @@ export class ExampleComponent {}
385
385
  > ```
386
386
 
387
387
  Inputs: `hubTooltip` (text), `hubTooltipPlacement` (`top` | `bottom` | `left` | `right`,
388
- default `top`), `hubTooltipDelay` (fade ms, default `150`), `hubTooltipOffset` (px, default `8`).
388
+ default `top`), `hubTooltipDelay` (fade ms, default `150`), `hubTooltipShowDelay` (ms a hover has to last before
389
+ the tooltip opens, default `0`; keyboard focus always opens it at once), `hubTooltipOffset` (px, default `8`).
389
390
 
390
391
  **The placement is a preference, not an instruction (since 22.16.0).** A tooltip that would open
391
392
  off the edge of the window opens on the opposite side instead, at all four edges, and one centred
@@ -816,7 +817,7 @@ library, because their selectors and data models differ.
816
817
 
817
818
  ### Directives
818
819
 
819
- - `HubTooltipDirective` (`[hubTooltip]`) - Tooltip on hover/focus, flipped away from the window edges. Inputs: `hubTooltip`, `hubTooltipPlacement`, `hubTooltipDelay`, `hubTooltipOffset`
820
+ - `HubTooltipDirective` (`[hubTooltip]`) - Tooltip on hover/focus, flipped away from the window edges. Inputs: `hubTooltip`, `hubTooltipPlacement`, `hubTooltipDelay`, `hubTooltipShowDelay`, `hubTooltipOffset`
820
821
  - `HubOverflowTooltipDirective` (`[hubOverflowTooltip]`) - Tooltip shown only while the label is truncated. Inputs: `hubOverflowTooltip`, `placement`, `hubOverflowTooltipMeasure` (CSS selector, resolved inside the host, naming the box whose truncation decides it; defaults to the host)
821
822
  - `provideHubTooltip(adapter: HubTooltipAdapter)` and `HUB_TOOLTIP_ADAPTER` - Swap the implementation behind `[hubOverflowTooltip]`, app-wide or per subtree; defaults to `hubTooltipAdapter`
822
823
 
@@ -4068,11 +4068,13 @@ let nextTooltipId = 0;
4068
4068
  class HubTooltipController {
4069
4069
  host;
4070
4070
  tooltipEl = null;
4071
+ showTimeout = null;
4071
4072
  hideTimeout = null;
4072
4073
  leaveTimeout = null;
4073
4074
  text = '';
4074
4075
  placement = 'top';
4075
4076
  delay = 150;
4077
+ showDelay = 0;
4076
4078
  offset = 8;
4077
4079
  /**
4078
4080
  * Side the bubble is actually on, which is the requested placement until the window says
@@ -4085,6 +4087,7 @@ class HubTooltipController {
4085
4087
  /** Id of this controller's bubble, minted once so the host can be described by it. */
4086
4088
  tooltipId = `hub-tooltip-${++nextTooltipId}`;
4087
4089
  onShow = () => this.show();
4090
+ onPointerEnter = () => this.scheduleShow();
4088
4091
  onHide = () => this.hide();
4089
4092
  onPointerLeave = () => this.scheduleHide();
4090
4093
  onTooltipEnter = () => this.retain();
@@ -4115,7 +4118,7 @@ class HubTooltipController {
4115
4118
  this.doc = host.ownerDocument;
4116
4119
  this.view = this.doc.defaultView;
4117
4120
  this.setOptions(options);
4118
- this.host.addEventListener('mouseenter', this.onShow);
4121
+ this.host.addEventListener('mouseenter', this.onPointerEnter);
4119
4122
  this.host.addEventListener('focus', this.onShow);
4120
4123
  this.host.addEventListener('mouseleave', this.onPointerLeave);
4121
4124
  this.host.addEventListener('blur', this.onHide);
@@ -4151,21 +4154,34 @@ class HubTooltipController {
4151
4154
  if (options.delay != null) {
4152
4155
  this.delay = options.delay;
4153
4156
  }
4157
+ if (options.showDelay != null) {
4158
+ this.showDelay = Math.max(0, options.showDelay);
4159
+ }
4154
4160
  if (options.offset != null) {
4155
4161
  this.offset = options.offset;
4156
4162
  }
4157
4163
  }
4158
4164
  /** Detaches listeners and removes any live tooltip element. */
4159
4165
  destroy() {
4160
- this.host.removeEventListener('mouseenter', this.onShow);
4166
+ this.host.removeEventListener('mouseenter', this.onPointerEnter);
4161
4167
  this.host.removeEventListener('focus', this.onShow);
4162
4168
  this.host.removeEventListener('mouseleave', this.onPointerLeave);
4163
4169
  this.host.removeEventListener('blur', this.onHide);
4164
4170
  this.host.removeEventListener('click', this.onHide);
4165
4171
  this.removeElement();
4166
4172
  }
4173
+ /** Waits for a sustained hover before opening, while retaining an already visible bubble. */
4174
+ scheduleShow() {
4175
+ this.clearShowTimeout();
4176
+ if (this.tooltipEl || this.showDelay === 0) {
4177
+ this.show();
4178
+ return;
4179
+ }
4180
+ this.showTimeout = setTimeout(() => this.show(), this.showDelay);
4181
+ }
4167
4182
  /** Creates, positions and reveals the tooltip element. */
4168
4183
  show() {
4184
+ this.clearShowTimeout();
4169
4185
  if (!this.text) {
4170
4186
  return;
4171
4187
  }
@@ -4218,6 +4234,7 @@ class HubTooltipController {
4218
4234
  * offset opens between host and bubble without the label vanishing on the way.
4219
4235
  */
4220
4236
  scheduleHide() {
4237
+ this.clearShowTimeout();
4221
4238
  if (!this.tooltipEl) {
4222
4239
  return;
4223
4240
  }
@@ -4235,6 +4252,7 @@ class HubTooltipController {
4235
4252
  }
4236
4253
  /** Fades the tooltip out and removes it after the fade completes. */
4237
4254
  hide() {
4255
+ this.clearShowTimeout();
4238
4256
  this.clearLeaveTimeout();
4239
4257
  if (!this.tooltipEl) {
4240
4258
  return;
@@ -4248,6 +4266,7 @@ class HubTooltipController {
4248
4266
  }
4249
4267
  /** Removes the tooltip element immediately. */
4250
4268
  removeElement() {
4269
+ this.clearShowTimeout();
4251
4270
  this.clearHideTimeout();
4252
4271
  this.clearLeaveTimeout();
4253
4272
  if (this.tooltipEl) {
@@ -4304,6 +4323,13 @@ class HubTooltipController {
4304
4323
  }
4305
4324
  }
4306
4325
  }
4326
+ /** Cancels hover work when the pointer leaves or the host is destroyed. */
4327
+ clearShowTimeout() {
4328
+ if (this.showTimeout !== null) {
4329
+ clearTimeout(this.showTimeout);
4330
+ this.showTimeout = null;
4331
+ }
4332
+ }
4307
4333
  clearHideTimeout() {
4308
4334
  if (this.hideTimeout !== null) {
4309
4335
  clearTimeout(this.hideTimeout);
@@ -4471,6 +4497,8 @@ class HubTooltipDirective {
4471
4497
  placement = input('top', { ...(ngDevMode ? { debugName: "placement" } : /* istanbul ignore next */ {}), alias: 'hubTooltipPlacement' });
4472
4498
  /** Fade duration in milliseconds, also used as the removal delay on hide. */
4473
4499
  delay = input(150, { ...(ngDevMode ? { debugName: "delay" } : /* istanbul ignore next */ {}), alias: 'hubTooltipDelay' });
4500
+ /** Pointer hover wait in milliseconds; keyboard focus remains immediate. */
4501
+ showDelay = input(0, { ...(ngDevMode ? { debugName: "showDelay" } : /* istanbul ignore next */ {}), alias: 'hubTooltipShowDelay' });
4474
4502
  /** Gap in pixels between the host and the tooltip. */
4475
4503
  offset = input(8, { ...(ngDevMode ? { debugName: "offset" } : /* istanbul ignore next */ {}), alias: 'hubTooltipOffset' });
4476
4504
  host = inject(ElementRef);
@@ -4480,6 +4508,7 @@ class HubTooltipDirective {
4480
4508
  this.controller.setOptions({
4481
4509
  placement: this.placement(),
4482
4510
  delay: this.delay(),
4511
+ showDelay: this.showDelay(),
4483
4512
  offset: this.offset()
4484
4513
  });
4485
4514
  this.controller.setText(this.text());
@@ -4490,14 +4519,14 @@ class HubTooltipDirective {
4490
4519
  this.controller.destroy();
4491
4520
  }
4492
4521
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4493
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: HubTooltipDirective, isStandalone: true, selector: "[hubTooltip]", inputs: { text: { classPropertyName: "text", publicName: "hubTooltip", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "hubTooltipPlacement", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "hubTooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "hubTooltipOffset", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
4522
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: HubTooltipDirective, isStandalone: true, selector: "[hubTooltip]", inputs: { text: { classPropertyName: "text", publicName: "hubTooltip", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "hubTooltipPlacement", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "hubTooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "hubTooltipShowDelay", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "hubTooltipOffset", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
4494
4523
  }
4495
4524
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubTooltipDirective, decorators: [{
4496
4525
  type: Directive,
4497
4526
  args: [{
4498
4527
  selector: '[hubTooltip]'
4499
4528
  }]
4500
- }], ctorParameters: () => [], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltip", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipPlacement", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipDelay", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipOffset", required: false }] }] } });
4529
+ }], ctorParameters: () => [], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltip", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipPlacement", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipDelay", required: false }] }], showDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipShowDelay", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipOffset", required: false }] }] } });
4501
4530
 
4502
4531
  /**
4503
4532
  * Shows a tooltip with the given text **only while the host element is truncated**