@lucca/prisme 22.1.0-rc.1 → 22.1.0-rc.2
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/fesm2022/lucca-prisme-button.mjs +2 -2
- package/fesm2022/lucca-prisme-button.mjs.map +1 -1
- package/fesm2022/lucca-prisme-icon.mjs +10 -352
- package/fesm2022/lucca-prisme-icon.mjs.map +1 -1
- package/fesm2022/lucca-prisme-numeric-badge.mjs +1 -1
- package/fesm2022/lucca-prisme-numeric-badge.mjs.map +1 -1
- package/fesm2022/lucca-prisme-skeleton.mjs +10 -10
- package/fesm2022/lucca-prisme-skeleton.mjs.map +1 -1
- package/fesm2022/lucca-prisme-tag.mjs +2 -2
- package/fesm2022/lucca-prisme-tag.mjs.map +1 -1
- package/fesm2022/lucca-prisme-tooltip.mjs +140 -68
- package/fesm2022/lucca-prisme-tooltip.mjs.map +1 -1
- package/package.json +3 -7
- package/types/lucca-prisme-icon.d.ts +4 -14
- package/types/lucca-prisme-tooltip.d.ts +6 -2
- package/fesm2022/lucca-prisme-safe-content.mjs +0 -48
- package/fesm2022/lucca-prisme-safe-content.mjs.map +0 -1
- package/types/lucca-prisme-safe-content.d.ts +0 -12
|
@@ -31,6 +31,8 @@ class LuTooltipPanelComponent {
|
|
|
31
31
|
this.mouseLeave$ = new Subject();
|
|
32
32
|
this.content = signal(null, /* @ts-ignore */
|
|
33
33
|
...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
|
|
34
|
+
this.enterDelay = signal(300, /* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "enterDelay" }] : /* istanbul ignore next */ []));
|
|
34
36
|
this.contentPositionClasses = signal({}, /* @ts-ignore */
|
|
35
37
|
...(ngDevMode ? [{ debugName: "contentPositionClasses" }] : /* istanbul ignore next */ []));
|
|
36
38
|
}
|
|
@@ -43,7 +45,7 @@ class LuTooltipPanelComponent {
|
|
|
43
45
|
});
|
|
44
46
|
}
|
|
45
47
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LuTooltipPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
46
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: LuTooltipPanelComponent, isStandalone: true, selector: "lu-tooltip-panel,pr-tooltip-panel", host: { attributes: { "role": "tooltip" }, listeners: { "mouseenter": "mouseEnter$.next()", "mouseleave": "mouseLeave$.next()" } }, ngImport: i0, template: "@if (content(); as content) {\n\t<div
|
|
48
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: LuTooltipPanelComponent, isStandalone: true, selector: "lu-tooltip-panel,pr-tooltip-panel", host: { attributes: { "role": "tooltip" }, listeners: { "mouseenter": "mouseEnter$.next()", "mouseleave": "mouseLeave$.next()" } }, ngImport: i0, template: "@if (content(); as content) {\n\t<div\n\t\tclass=\"tooltip\"\n\t\t[class]=\"contentPositionClasses()\"\n\t\t[innerHtml]=\"content\"\n\t\t[style.--components-tooltip-animationDelay]=\"enterDelay() + 'ms'\"\n\t></div>\n}\n", styles: ["@layer components{.tooltip{--components-tooltip-background-color: var(--palettes-neutral-900);--components-tooltip-color: var(--pr-t-color-text-reverse);--components-tooltip-max-width: 15rem;--components-tooltip-transformOrigin: center;--components-tooltip-margin: 0;--components-tooltip-animationDelay: .3s;background-color:var(--components-tooltip-background-color);color:var(--components-tooltip-color);padding-block:var(--pr-t-spacings-50);padding-inline:var(--pr-t-spacings-100);max-inline-size:var(--components-tooltip-max-width);border-radius:var(--pr-t-border-radius-default);font:var(--pr-t-font-body-XS);transform-origin:var(--components-tooltip-transformOrigin);margin:var(--components-tooltip-margin);text-align:center;inline-size:fit-content;animation-name:scaleIn,tooltipPointerEventsIn;animation-delay:var(--components-tooltip-animationDelay);animation-duration:var(--commons-animations-durations-fast);animation-iteration-count:1;animation-fill-mode:backwards;overflow-wrap:break-word}@keyframes scaleIn{0%{transform:scale(0)}to{transform:scale(1)}}@keyframes tooltipPointerEventsIn{0%{pointer-events:none}1%{pointer-events:auto}}.tooltip:empty{display:none}@supports (background-image: -webkit-named-image(i)){@media(hover:hover){.tooltip_trigger.is-whenEllipsis:after{content:\"\";display:block}}}}@layer mods{.tooltip.is-above{--components-tooltip-transformOrigin: bottom center}.tooltip.is-below{--components-tooltip-transformOrigin: top center}.tooltip.is-before{--components-tooltip-transformOrigin: center right}.tooltip.is-before.is-above{--components-tooltip-transformOrigin: bottom right}.tooltip.is-before.is-below{--components-tooltip-transformOrigin: top right}.tooltip.is-after{--components-tooltip-transformOrigin: center left}.tooltip.is-after.is-above{--components-tooltip-transformOrigin: bottom left}.tooltip.is-after.is-below{--components-tooltip-transformOrigin: top left}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
47
49
|
}
|
|
48
50
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LuTooltipPanelComponent, decorators: [{
|
|
49
51
|
type: Component,
|
|
@@ -51,7 +53,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
51
53
|
role: 'tooltip',
|
|
52
54
|
'(mouseenter)': 'mouseEnter$.next()',
|
|
53
55
|
'(mouseleave)': 'mouseLeave$.next()',
|
|
54
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (content(); as content) {\n\t<div
|
|
56
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (content(); as content) {\n\t<div\n\t\tclass=\"tooltip\"\n\t\t[class]=\"contentPositionClasses()\"\n\t\t[innerHtml]=\"content\"\n\t\t[style.--components-tooltip-animationDelay]=\"enterDelay() + 'ms'\"\n\t></div>\n}\n", styles: ["@layer components{.tooltip{--components-tooltip-background-color: var(--palettes-neutral-900);--components-tooltip-color: var(--pr-t-color-text-reverse);--components-tooltip-max-width: 15rem;--components-tooltip-transformOrigin: center;--components-tooltip-margin: 0;--components-tooltip-animationDelay: .3s;background-color:var(--components-tooltip-background-color);color:var(--components-tooltip-color);padding-block:var(--pr-t-spacings-50);padding-inline:var(--pr-t-spacings-100);max-inline-size:var(--components-tooltip-max-width);border-radius:var(--pr-t-border-radius-default);font:var(--pr-t-font-body-XS);transform-origin:var(--components-tooltip-transformOrigin);margin:var(--components-tooltip-margin);text-align:center;inline-size:fit-content;animation-name:scaleIn,tooltipPointerEventsIn;animation-delay:var(--components-tooltip-animationDelay);animation-duration:var(--commons-animations-durations-fast);animation-iteration-count:1;animation-fill-mode:backwards;overflow-wrap:break-word}@keyframes scaleIn{0%{transform:scale(0)}to{transform:scale(1)}}@keyframes tooltipPointerEventsIn{0%{pointer-events:none}1%{pointer-events:auto}}.tooltip:empty{display:none}@supports (background-image: -webkit-named-image(i)){@media(hover:hover){.tooltip_trigger.is-whenEllipsis:after{content:\"\";display:block}}}}@layer mods{.tooltip.is-above{--components-tooltip-transformOrigin: bottom center}.tooltip.is-below{--components-tooltip-transformOrigin: top center}.tooltip.is-before{--components-tooltip-transformOrigin: center right}.tooltip.is-before.is-above{--components-tooltip-transformOrigin: bottom right}.tooltip.is-before.is-below{--components-tooltip-transformOrigin: top right}.tooltip.is-after{--components-tooltip-transformOrigin: center left}.tooltip.is-after.is-above{--components-tooltip-transformOrigin: bottom left}.tooltip.is-after.is-below{--components-tooltip-transformOrigin: top left}}\n"] }]
|
|
55
57
|
}] });
|
|
56
58
|
|
|
57
59
|
/**
|
|
@@ -117,6 +119,14 @@ class LuTooltipTriggerDirective {
|
|
|
117
119
|
#hasEllipsis;
|
|
118
120
|
// reusable hidden clone, one per directive, used to measure the unconstrained width
|
|
119
121
|
#clone;
|
|
122
|
+
// Each measurement phase hands over to the next one through these signals rather than through
|
|
123
|
+
// the value `afterRenderEffect` pipes between phases. A phase only receives that value when the
|
|
124
|
+
// phases before it ran in the same pass; a directive created while the after-render hooks are
|
|
125
|
+
// running starts mid-pipeline and gets Angular's `registerCleanupFn` as its first argument
|
|
126
|
+
// instead. Calling it then registers `undefined` as a cleanup function, which throws
|
|
127
|
+
// `fn is not a function` when the view is destroyed, far away from the cause.
|
|
128
|
+
#measurementRequest;
|
|
129
|
+
#preparedMeasurement;
|
|
120
130
|
#action;
|
|
121
131
|
#realAction;
|
|
122
132
|
#effectRef;
|
|
@@ -138,13 +148,13 @@ class LuTooltipTriggerDirective {
|
|
|
138
148
|
...(ngDevMode ? [{ debugName: "prTooltip" }] : /* istanbul ignore next */ []));
|
|
139
149
|
this.tooltipContent = computed(() => this.luTooltip() || this.prTooltip(), /* @ts-ignore */
|
|
140
150
|
...(ngDevMode ? [{ debugName: "tooltipContent" }] : /* istanbul ignore next */ []));
|
|
141
|
-
this.luTooltipEnterDelay = input(
|
|
151
|
+
this.luTooltipEnterDelay = input(0, { ...(ngDevMode ? { debugName: "luTooltipEnterDelay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
142
152
|
this.prTooltipEnterDelay = input(300, { ...(ngDevMode ? { debugName: "prTooltipEnterDelay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
143
|
-
this.tooltipEnterDelay = computed(() => this.
|
|
153
|
+
this.tooltipEnterDelay = computed(() => this.luTooltipEnterDelay() || this.prTooltipEnterDelay(), /* @ts-ignore */
|
|
144
154
|
...(ngDevMode ? [{ debugName: "tooltipEnterDelay" }] : /* istanbul ignore next */ []));
|
|
145
|
-
this.luTooltipLeaveDelay = input(
|
|
155
|
+
this.luTooltipLeaveDelay = input(0, { ...(ngDevMode ? { debugName: "luTooltipLeaveDelay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
146
156
|
this.prTooltipLeaveDelay = input(100, { ...(ngDevMode ? { debugName: "prTooltipLeaveDelay" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
147
|
-
this.tooltipLeaveDelay = computed(() => this.
|
|
157
|
+
this.tooltipLeaveDelay = computed(() => this.luTooltipLeaveDelay() || this.prTooltipLeaveDelay(), /* @ts-ignore */
|
|
148
158
|
...(ngDevMode ? [{ debugName: "tooltipLeaveDelay" }] : /* istanbul ignore next */ []));
|
|
149
159
|
this.luTooltipDisabled = input(false, { ...(ngDevMode ? { debugName: "luTooltipDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
150
160
|
this.prTooltipDisabled = input(false, { ...(ngDevMode ? { debugName: "prTooltipDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
@@ -154,11 +164,11 @@ class LuTooltipTriggerDirective {
|
|
|
154
164
|
this.prTooltipOnlyForDisplay = input(false, { ...(ngDevMode ? { debugName: "prTooltipOnlyForDisplay" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
155
165
|
this.tooltipOnlyForDisplay = computed(() => this.prTooltipOnlyForDisplay() || this.luTooltipOnlyForDisplay(), /* @ts-ignore */
|
|
156
166
|
...(ngDevMode ? [{ debugName: "tooltipOnlyForDisplay" }] : /* istanbul ignore next */ []));
|
|
157
|
-
this.luTooltipPosition = input(
|
|
167
|
+
this.luTooltipPosition = input(null, /* @ts-ignore */
|
|
158
168
|
...(ngDevMode ? [{ debugName: "luTooltipPosition" }] : /* istanbul ignore next */ []));
|
|
159
169
|
this.prTooltipPosition = input('above', /* @ts-ignore */
|
|
160
170
|
...(ngDevMode ? [{ debugName: "prTooltipPosition" }] : /* istanbul ignore next */ []));
|
|
161
|
-
this.tooltipPosition = computed(() => this.
|
|
171
|
+
this.tooltipPosition = computed(() => this.luTooltipPosition() ?? this.prTooltipPosition(), /* @ts-ignore */
|
|
162
172
|
...(ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ []));
|
|
163
173
|
this.luTooltipWhenEllipsisInput = input(false, { ...(ngDevMode ? { debugName: "luTooltipWhenEllipsisInput" } : /* istanbul ignore next */ {}), alias: 'luTooltipWhenEllipsis', transform: booleanAttribute });
|
|
164
174
|
this.prTooltipWhenEllipsisInput = input(false, { ...(ngDevMode ? { debugName: "prTooltipWhenEllipsisInput" } : /* istanbul ignore next */ {}), alias: 'prTooltipWhenEllipsis', transform: booleanAttribute });
|
|
@@ -168,12 +178,18 @@ class LuTooltipTriggerDirective {
|
|
|
168
178
|
...(ngDevMode ? [{ debugName: "prTooltipWhenEllipsis" }] : /* istanbul ignore next */ []));
|
|
169
179
|
this.tooltipWhenEllipsis = computed(() => this.prTooltipWhenEllipsis() || this.luTooltipWhenEllipsis(), /* @ts-ignore */
|
|
170
180
|
...(ngDevMode ? [{ debugName: "tooltipWhenEllipsis" }] : /* istanbul ignore next */ []));
|
|
171
|
-
this.luTooltipAnchor = input(
|
|
181
|
+
this.luTooltipAnchor = input(null, /* @ts-ignore */
|
|
172
182
|
...(ngDevMode ? [{ debugName: "luTooltipAnchor" }] : /* istanbul ignore next */ []));
|
|
173
183
|
this.prTooltipAnchor = input(this.#host, /* @ts-ignore */
|
|
174
184
|
...(ngDevMode ? [{ debugName: "prTooltipAnchor" }] : /* istanbul ignore next */ []));
|
|
175
|
-
this.tooltipAnchor = computed(() => this.
|
|
185
|
+
this.tooltipAnchor = computed(() => this.luTooltipAnchor() || this.prTooltipAnchor(), /* @ts-ignore */
|
|
176
186
|
...(ngDevMode ? [{ debugName: "tooltipAnchor" }] : /* istanbul ignore next */ []));
|
|
187
|
+
this.luTooltipTriggerAnchor = input(null, /* @ts-ignore */
|
|
188
|
+
...(ngDevMode ? [{ debugName: "luTooltipTriggerAnchor" }] : /* istanbul ignore next */ []));
|
|
189
|
+
this.prTooltipTriggerAnchor = input(null, /* @ts-ignore */
|
|
190
|
+
...(ngDevMode ? [{ debugName: "prTooltipTriggerAnchor" }] : /* istanbul ignore next */ []));
|
|
191
|
+
this.tooltipTriggerAnchor = computed(() => this.luTooltipTriggerAnchor() || this.prTooltipTriggerAnchor(), /* @ts-ignore */
|
|
192
|
+
...(ngDevMode ? [{ debugName: "tooltipTriggerAnchor" }] : /* istanbul ignore next */ []));
|
|
177
193
|
this.id = input(`${this.#host.nativeElement.tagName.toLowerCase()}-tooltip-${nextId++}`, /* @ts-ignore */
|
|
178
194
|
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
179
195
|
this.ariaDescribedBy = computed(() => {
|
|
@@ -196,6 +212,16 @@ class LuTooltipTriggerDirective {
|
|
|
196
212
|
// written only from the `read` phase of the afterRenderEffect below
|
|
197
213
|
this.#hasEllipsis = signal(false, /* @ts-ignore */
|
|
198
214
|
...(ngDevMode ? [{ debugName: "#hasEllipsis" }] : /* istanbul ignore next */ []));
|
|
215
|
+
// Each measurement phase hands over to the next one through these signals rather than through
|
|
216
|
+
// the value `afterRenderEffect` pipes between phases. A phase only receives that value when the
|
|
217
|
+
// phases before it ran in the same pass; a directive created while the after-render hooks are
|
|
218
|
+
// running starts mid-pipeline and gets Angular's `registerCleanupFn` as its first argument
|
|
219
|
+
// instead. Calling it then registers `undefined` as a cleanup function, which throws
|
|
220
|
+
// `fn is not a function` when the view is destroyed, far away from the cause.
|
|
221
|
+
this.#measurementRequest = signal(null, /* @ts-ignore */
|
|
222
|
+
...(ngDevMode ? [{ debugName: "#measurementRequest" }] : /* istanbul ignore next */ []));
|
|
223
|
+
this.#preparedMeasurement = signal(null, /* @ts-ignore */
|
|
224
|
+
...(ngDevMode ? [{ debugName: "#preparedMeasurement" }] : /* istanbul ignore next */ []));
|
|
199
225
|
this.#action = signal(null, /* @ts-ignore */
|
|
200
226
|
...(ngDevMode ? [{ debugName: "#action" }] : /* istanbul ignore next */ []));
|
|
201
227
|
this.#realAction = linkedSignal({ ...(ngDevMode ? { debugName: "#realAction" } : /* istanbul ignore next */ {}), source: this.#action,
|
|
@@ -216,11 +242,11 @@ class LuTooltipTriggerDirective {
|
|
|
216
242
|
// pane the focus moved into when it last left this trigger, or null
|
|
217
243
|
this.#focusLeftToPane = null;
|
|
218
244
|
this.#destroyRef.onDestroy(() => (this.#destroyed = true));
|
|
219
|
-
//
|
|
245
|
+
// content attach/detach — immediate on open, VoiceOver/Safari misses a late aria-describedby
|
|
220
246
|
toObservable(this.#realAction)
|
|
221
|
-
.pipe(filter(isNotNil), debounce((action) => timer(action === 'open' ?
|
|
222
|
-
if (
|
|
223
|
-
this.
|
|
247
|
+
.pipe(filter(isNotNil), debounce((action) => timer(action === 'open' ? 0 : this.tooltipLeaveDelay())), tap((action) => {
|
|
248
|
+
if (action === 'open') {
|
|
249
|
+
this.attachTooltip();
|
|
224
250
|
}
|
|
225
251
|
else {
|
|
226
252
|
this.closeTooltip();
|
|
@@ -235,6 +261,22 @@ class LuTooltipTriggerDirective {
|
|
|
235
261
|
this.setAccessibilityProperties(null);
|
|
236
262
|
}
|
|
237
263
|
});
|
|
264
|
+
effect((onCleanup) => {
|
|
265
|
+
const trigger = this.#resolveTriggerAnchorElement() ?? this.#host.nativeElement;
|
|
266
|
+
const unlisten = [
|
|
267
|
+
this.#renderer.listen(trigger, 'mouseenter', () => this.onMouseEnter()),
|
|
268
|
+
this.#renderer.listen(trigger, 'mouseleave', () => this.onMouseLeave()),
|
|
269
|
+
this.#renderer.listen(trigger, 'focus', () => this.onFocus()),
|
|
270
|
+
this.#renderer.listen(trigger, 'blur', () => this.onBlur()),
|
|
271
|
+
this.#renderer.listen(trigger, 'focusout', (event) => this.onFocusOut(event)),
|
|
272
|
+
this.#renderer.listen(trigger, 'keydown', (event) => {
|
|
273
|
+
if (event.key === 'Escape') {
|
|
274
|
+
this.onEscape(event);
|
|
275
|
+
}
|
|
276
|
+
}),
|
|
277
|
+
];
|
|
278
|
+
onCleanup(() => unlisten.forEach((fn) => fn()));
|
|
279
|
+
});
|
|
238
280
|
// Defer the first measurement until the element is near the viewport, then stop tracking
|
|
239
281
|
// visibility: scrolling must not re-measure, so we arm the resize/mutation observers once.
|
|
240
282
|
// A single shared IntersectionObserver handles every tooltip (see TooltipVisibilityObserver).
|
|
@@ -251,35 +293,27 @@ class LuTooltipTriggerDirective {
|
|
|
251
293
|
// This keeps the whole batch to a single forced reflow instead of one reflow per element.
|
|
252
294
|
afterRenderEffect({
|
|
253
295
|
earlyRead: () => {
|
|
254
|
-
|
|
255
|
-
const measured = this.#measureTrigger() > 0;
|
|
256
|
-
const shouldMeasure = measured && !this.tooltipDisabled() && this.tooltipWhenEllipsis();
|
|
257
|
-
if (!shouldMeasure) {
|
|
258
|
-
return { measure: false };
|
|
259
|
-
}
|
|
260
|
-
const host = this.#host.nativeElement;
|
|
261
|
-
const hostStyle = getComputedStyle(host);
|
|
262
|
-
// No need to run a test if the element is not truncated
|
|
263
|
-
// or if its `display` property is set to `inline`
|
|
264
|
-
// (especially for Safari, which still calculates a width, unlike other browsers)
|
|
265
|
-
if (hostStyle.textOverflow !== 'ellipsis' || hostStyle.display === 'inline') {
|
|
266
|
-
return { measure: false };
|
|
267
|
-
}
|
|
268
|
-
return { measure: true, host, hostStyle };
|
|
296
|
+
this.#measurementRequest.set(this.#readMeasurementRequest());
|
|
269
297
|
},
|
|
270
|
-
write: (
|
|
271
|
-
const
|
|
272
|
-
if (!
|
|
273
|
-
|
|
298
|
+
write: () => {
|
|
299
|
+
const request = this.#measurementRequest();
|
|
300
|
+
if (!request) {
|
|
301
|
+
this.#preparedMeasurement.set(null);
|
|
302
|
+
return;
|
|
274
303
|
}
|
|
275
304
|
const clone = (this.#clone ??= this.#createClone());
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
305
|
+
Object.assign(clone.style, request.cloneStyles);
|
|
306
|
+
const html = request.host.innerHTML;
|
|
307
|
+
// Writing the same markup back would invalidate layout for nothing, and every tooltip
|
|
308
|
+
// measured after this one would then pay for a new layout on its first geometry read.
|
|
309
|
+
if (clone.innerHTML !== html) {
|
|
310
|
+
clone.innerHTML = html;
|
|
311
|
+
}
|
|
312
|
+
this.#preparedMeasurement.set({ host: request.host, clone });
|
|
279
313
|
},
|
|
280
|
-
read: (
|
|
281
|
-
const measurement =
|
|
282
|
-
if (!measurement
|
|
314
|
+
read: () => {
|
|
315
|
+
const measurement = this.#preparedMeasurement();
|
|
316
|
+
if (!measurement) {
|
|
283
317
|
this.#hasEllipsis.set(false);
|
|
284
318
|
return;
|
|
285
319
|
}
|
|
@@ -304,6 +338,8 @@ class LuTooltipTriggerDirective {
|
|
|
304
338
|
this.#measurementObserversArmed = true;
|
|
305
339
|
const el = this.#host.nativeElement;
|
|
306
340
|
const bump = () => this.#measureTrigger.update((v) => v + 1);
|
|
341
|
+
// `observe` always delivers an initial notification, which doubles as the first measurement:
|
|
342
|
+
// asking for one here as well would measure every tooltip on the page twice.
|
|
307
343
|
const resizeObserver = new ResizeObserver(() => bump());
|
|
308
344
|
resizeObserver.observe(el);
|
|
309
345
|
const mutationObserver = new MutationObserver(() => bump());
|
|
@@ -312,8 +348,26 @@ class LuTooltipTriggerDirective {
|
|
|
312
348
|
resizeObserver.disconnect();
|
|
313
349
|
mutationObserver.disconnect();
|
|
314
350
|
});
|
|
315
|
-
|
|
316
|
-
|
|
351
|
+
}
|
|
352
|
+
// Reads everything the measurement needs from the host, in the read-only phase.
|
|
353
|
+
#readMeasurementRequest() {
|
|
354
|
+
// reading the trigger registers the dependency; 0 means "not measured yet"
|
|
355
|
+
const measured = this.#measureTrigger() > 0;
|
|
356
|
+
if (!measured || this.tooltipDisabled() || !this.tooltipWhenEllipsis()) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
const host = this.#host.nativeElement;
|
|
360
|
+
// A `CSSStyleDeclaration` is live: reading one property from it in the write phase, after
|
|
361
|
+
// another tooltip has already mutated the DOM, forces a full style recalculation — once per
|
|
362
|
+
// tooltip on the page. Every value is therefore copied out here.
|
|
363
|
+
const { textOverflow, display, padding, borderWidth, borderStyle, boxSizing, fontFamily, fontWeight, fontStyle, fontSize } = getComputedStyle(host);
|
|
364
|
+
// No need to run a test if the element is not truncated
|
|
365
|
+
// or if its `display` property is set to `inline`
|
|
366
|
+
// (especially for Safari, which still calculates a width, unlike other browsers)
|
|
367
|
+
if (textOverflow !== 'ellipsis' || display === 'inline') {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
return { host, cloneStyles: { padding, borderWidth, borderStyle, boxSizing, fontFamily, fontWeight, fontStyle, fontSize } };
|
|
317
371
|
}
|
|
318
372
|
#createClone() {
|
|
319
373
|
const clone = this.#document.createElement('div');
|
|
@@ -333,10 +387,6 @@ class LuTooltipTriggerDirective {
|
|
|
333
387
|
this.#document.body.appendChild(clone);
|
|
334
388
|
return clone;
|
|
335
389
|
}
|
|
336
|
-
#applyClonedStyles(clone, hostStyle) {
|
|
337
|
-
const { padding, borderWidth, borderStyle, boxSizing, fontFamily, fontWeight, fontStyle, fontSize } = hostStyle;
|
|
338
|
-
Object.assign(clone.style, { padding, borderWidth, borderStyle, boxSizing, fontFamily, fontWeight, fontStyle, fontSize });
|
|
339
|
-
}
|
|
340
390
|
onMouseEnter() {
|
|
341
391
|
this.#action.set('open');
|
|
342
392
|
}
|
|
@@ -391,18 +441,35 @@ class LuTooltipTriggerDirective {
|
|
|
391
441
|
}
|
|
392
442
|
prepareOverlay() {
|
|
393
443
|
if (this.overlayRef) {
|
|
394
|
-
return;
|
|
444
|
+
return this.overlayRef;
|
|
395
445
|
}
|
|
396
|
-
|
|
446
|
+
const overlayRef = this.#overlay.create({
|
|
397
447
|
scrollStrategy: this.#overlay.scrollStrategies.close(),
|
|
398
448
|
disposeOnNavigation: true,
|
|
399
449
|
});
|
|
450
|
+
// `disposeOnNavigation` disposes the overlay on a history navigation (browser back/forward)
|
|
451
|
+
// while this directive may live on: forget it then, so the next opening creates a new one
|
|
452
|
+
// instead of attaching to a disposed overlay (`attach()` returns null).
|
|
453
|
+
overlayRef
|
|
454
|
+
.detachments()
|
|
455
|
+
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
456
|
+
.subscribe({
|
|
457
|
+
complete: () => {
|
|
458
|
+
if (this.overlayRef === overlayRef) {
|
|
459
|
+
delete this.overlayRef;
|
|
460
|
+
// the content effect writes to the disposed panel: a reopening would overwrite it without destroying it
|
|
461
|
+
this.#effectRef?.destroy();
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
});
|
|
400
465
|
const describedBy = this.ariaDescribedBy();
|
|
401
466
|
if (describedBy !== null) {
|
|
402
|
-
|
|
467
|
+
overlayRef.overlayElement.id = describedBy;
|
|
403
468
|
}
|
|
469
|
+
this.overlayRef = overlayRef;
|
|
470
|
+
return overlayRef;
|
|
404
471
|
}
|
|
405
|
-
|
|
472
|
+
attachTooltip() {
|
|
406
473
|
// A pending debounced 'open' is flushed when `toObservable(#realAction)` completes on
|
|
407
474
|
// destroy (`debounce` re-emits the held value on completion), i.e. AFTER ngOnDestroy has
|
|
408
475
|
// disposed the overlay. Opening then would recreate an overlay anchored to a detached
|
|
@@ -411,18 +478,11 @@ class LuTooltipTriggerDirective {
|
|
|
411
478
|
return;
|
|
412
479
|
}
|
|
413
480
|
const position = this.legacyPositionBuilder();
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
positionStrategy: position,
|
|
417
|
-
scrollStrategy: this.#overlay.scrollStrategies.close(),
|
|
418
|
-
disposeOnNavigation: true,
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
else {
|
|
422
|
-
this.overlayRef.updatePositionStrategy(position);
|
|
423
|
-
}
|
|
481
|
+
const overlayRef = this.prepareOverlay();
|
|
482
|
+
overlayRef.updatePositionStrategy(position);
|
|
424
483
|
const portal = new ComponentPortal(LuTooltipPanelComponent);
|
|
425
|
-
const ref =
|
|
484
|
+
const ref = overlayRef.attach(portal);
|
|
485
|
+
ref.instance.enterDelay.set(this.tooltipEnterDelay());
|
|
426
486
|
position.positionChanges
|
|
427
487
|
.pipe(takeUntilDestroyed(this.#destroyRef), map(({ connectionPair }) => connectionPair), startWith(position.positions[0]))
|
|
428
488
|
.subscribe(({ overlayX, overlayY }) => {
|
|
@@ -449,6 +509,9 @@ class LuTooltipTriggerDirective {
|
|
|
449
509
|
this.#effectRef?.destroy();
|
|
450
510
|
}
|
|
451
511
|
setAccessibilityProperties(tabindex) {
|
|
512
|
+
if (this.#resolveTriggerAnchorElement()) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
452
515
|
if (tabindex === null) {
|
|
453
516
|
this.#renderer.removeAttribute(this.#host.nativeElement, 'tabindex');
|
|
454
517
|
return;
|
|
@@ -549,6 +612,21 @@ class LuTooltipTriggerDirective {
|
|
|
549
612
|
return anchor;
|
|
550
613
|
}
|
|
551
614
|
}
|
|
615
|
+
#resolveTriggerAnchorElement() {
|
|
616
|
+
const triggerAnchor = this.tooltipTriggerAnchor();
|
|
617
|
+
if (isNil(triggerAnchor)) {
|
|
618
|
+
return null;
|
|
619
|
+
}
|
|
620
|
+
else if (triggerAnchor instanceof HTMLElement) {
|
|
621
|
+
return triggerAnchor;
|
|
622
|
+
}
|
|
623
|
+
else if ('getElementRef' in triggerAnchor) {
|
|
624
|
+
return triggerAnchor.getElementRef().nativeElement;
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
return triggerAnchor.nativeElement;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
552
630
|
invertVerticalPos(y) {
|
|
553
631
|
if (y === 'top') {
|
|
554
632
|
return 'bottom';
|
|
@@ -568,7 +646,7 @@ class LuTooltipTriggerDirective {
|
|
|
568
646
|
return x;
|
|
569
647
|
}
|
|
570
648
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LuTooltipTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
571
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: LuTooltipTriggerDirective, isStandalone: true, selector: "[luTooltip],[prTooltip]", inputs: { luTooltipInput: { classPropertyName: "luTooltipInput", publicName: "luTooltip", isSignal: true, isRequired: false, transformFunction: null }, prTooltipInput: { classPropertyName: "prTooltipInput", publicName: "prTooltip", isSignal: true, isRequired: false, transformFunction: null }, luTooltipEnterDelay: { classPropertyName: "luTooltipEnterDelay", publicName: "luTooltipEnterDelay", isSignal: true, isRequired: false, transformFunction: null }, prTooltipEnterDelay: { classPropertyName: "prTooltipEnterDelay", publicName: "prTooltipEnterDelay", isSignal: true, isRequired: false, transformFunction: null }, luTooltipLeaveDelay: { classPropertyName: "luTooltipLeaveDelay", publicName: "luTooltipLeaveDelay", isSignal: true, isRequired: false, transformFunction: null }, prTooltipLeaveDelay: { classPropertyName: "prTooltipLeaveDelay", publicName: "prTooltipLeaveDelay", isSignal: true, isRequired: false, transformFunction: null }, luTooltipDisabled: { classPropertyName: "luTooltipDisabled", publicName: "luTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, prTooltipDisabled: { classPropertyName: "prTooltipDisabled", publicName: "prTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, luTooltipOnlyForDisplay: { classPropertyName: "luTooltipOnlyForDisplay", publicName: "luTooltipOnlyForDisplay", isSignal: true, isRequired: false, transformFunction: null }, prTooltipOnlyForDisplay: { classPropertyName: "prTooltipOnlyForDisplay", publicName: "prTooltipOnlyForDisplay", isSignal: true, isRequired: false, transformFunction: null }, luTooltipPosition: { classPropertyName: "luTooltipPosition", publicName: "luTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, prTooltipPosition: { classPropertyName: "prTooltipPosition", publicName: "prTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, luTooltipWhenEllipsisInput: { classPropertyName: "luTooltipWhenEllipsisInput", publicName: "luTooltipWhenEllipsis", isSignal: true, isRequired: false, transformFunction: null }, prTooltipWhenEllipsisInput: { classPropertyName: "prTooltipWhenEllipsisInput", publicName: "prTooltipWhenEllipsis", isSignal: true, isRequired: false, transformFunction: null }, luTooltipAnchor: { classPropertyName: "luTooltipAnchor", publicName: "luTooltipAnchor", isSignal: true, isRequired: false, transformFunction: null }, prTooltipAnchor: { classPropertyName: "prTooltipAnchor", publicName: "prTooltipAnchor", isSignal: true, isRequired: false, transformFunction: null },
|
|
649
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: LuTooltipTriggerDirective, isStandalone: true, selector: "[luTooltip],[prTooltip]", inputs: { luTooltipInput: { classPropertyName: "luTooltipInput", publicName: "luTooltip", isSignal: true, isRequired: false, transformFunction: null }, prTooltipInput: { classPropertyName: "prTooltipInput", publicName: "prTooltip", isSignal: true, isRequired: false, transformFunction: null }, luTooltipEnterDelay: { classPropertyName: "luTooltipEnterDelay", publicName: "luTooltipEnterDelay", isSignal: true, isRequired: false, transformFunction: null }, prTooltipEnterDelay: { classPropertyName: "prTooltipEnterDelay", publicName: "prTooltipEnterDelay", isSignal: true, isRequired: false, transformFunction: null }, luTooltipLeaveDelay: { classPropertyName: "luTooltipLeaveDelay", publicName: "luTooltipLeaveDelay", isSignal: true, isRequired: false, transformFunction: null }, prTooltipLeaveDelay: { classPropertyName: "prTooltipLeaveDelay", publicName: "prTooltipLeaveDelay", isSignal: true, isRequired: false, transformFunction: null }, luTooltipDisabled: { classPropertyName: "luTooltipDisabled", publicName: "luTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, prTooltipDisabled: { classPropertyName: "prTooltipDisabled", publicName: "prTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, luTooltipOnlyForDisplay: { classPropertyName: "luTooltipOnlyForDisplay", publicName: "luTooltipOnlyForDisplay", isSignal: true, isRequired: false, transformFunction: null }, prTooltipOnlyForDisplay: { classPropertyName: "prTooltipOnlyForDisplay", publicName: "prTooltipOnlyForDisplay", isSignal: true, isRequired: false, transformFunction: null }, luTooltipPosition: { classPropertyName: "luTooltipPosition", publicName: "luTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, prTooltipPosition: { classPropertyName: "prTooltipPosition", publicName: "prTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, luTooltipWhenEllipsisInput: { classPropertyName: "luTooltipWhenEllipsisInput", publicName: "luTooltipWhenEllipsis", isSignal: true, isRequired: false, transformFunction: null }, prTooltipWhenEllipsisInput: { classPropertyName: "prTooltipWhenEllipsisInput", publicName: "prTooltipWhenEllipsis", isSignal: true, isRequired: false, transformFunction: null }, luTooltipAnchor: { classPropertyName: "luTooltipAnchor", publicName: "luTooltipAnchor", isSignal: true, isRequired: false, transformFunction: null }, prTooltipAnchor: { classPropertyName: "prTooltipAnchor", publicName: "prTooltipAnchor", isSignal: true, isRequired: false, transformFunction: null }, luTooltipTriggerAnchor: { classPropertyName: "luTooltipTriggerAnchor", publicName: "luTooltipTriggerAnchor", isSignal: true, isRequired: false, transformFunction: null }, prTooltipTriggerAnchor: { classPropertyName: "prTooltipTriggerAnchor", publicName: "prTooltipTriggerAnchor", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-describedby": "ariaDescribedBy()", "attr.id": "id()", "class.is-whenEllipsis": "luTooltipWhenEllipsis()" }, classAttribute: "tooltip_trigger" }, exportAs: ["luTooltip"], ngImport: i0 }); }
|
|
572
650
|
}
|
|
573
651
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LuTooltipTriggerDirective, decorators: [{
|
|
574
652
|
type: Directive,
|
|
@@ -578,17 +656,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
578
656
|
host: {
|
|
579
657
|
'[attr.aria-describedby]': 'ariaDescribedBy()',
|
|
580
658
|
'[attr.id]': 'id()',
|
|
581
|
-
'(mouseenter)': 'onMouseEnter()',
|
|
582
|
-
'(mouseleave)': 'onMouseLeave()',
|
|
583
|
-
'(focus)': 'onFocus()',
|
|
584
|
-
'(focusout)': 'onFocusOut($event)',
|
|
585
|
-
'(blur)': 'onBlur()',
|
|
586
|
-
'(keydown.escape)': 'onEscape($event)',
|
|
587
659
|
class: 'tooltip_trigger',
|
|
588
660
|
'[class.is-whenEllipsis]': 'luTooltipWhenEllipsis()',
|
|
589
661
|
},
|
|
590
662
|
}]
|
|
591
|
-
}], ctorParameters: () => [], propDecorators: { luTooltipInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltip", required: false }] }], prTooltipInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltip", required: false }] }], luTooltipEnterDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipEnterDelay", required: false }] }], prTooltipEnterDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipEnterDelay", required: false }] }], luTooltipLeaveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipLeaveDelay", required: false }] }], prTooltipLeaveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipLeaveDelay", required: false }] }], luTooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipDisabled", required: false }] }], prTooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipDisabled", required: false }] }], luTooltipOnlyForDisplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipOnlyForDisplay", required: false }] }], prTooltipOnlyForDisplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipOnlyForDisplay", required: false }] }], luTooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipPosition", required: false }] }], prTooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipPosition", required: false }] }], luTooltipWhenEllipsisInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipWhenEllipsis", required: false }] }], prTooltipWhenEllipsisInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipWhenEllipsis", required: false }] }], luTooltipAnchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipAnchor", required: false }] }], prTooltipAnchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipAnchor", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
663
|
+
}], ctorParameters: () => [], propDecorators: { luTooltipInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltip", required: false }] }], prTooltipInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltip", required: false }] }], luTooltipEnterDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipEnterDelay", required: false }] }], prTooltipEnterDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipEnterDelay", required: false }] }], luTooltipLeaveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipLeaveDelay", required: false }] }], prTooltipLeaveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipLeaveDelay", required: false }] }], luTooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipDisabled", required: false }] }], prTooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipDisabled", required: false }] }], luTooltipOnlyForDisplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipOnlyForDisplay", required: false }] }], prTooltipOnlyForDisplay: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipOnlyForDisplay", required: false }] }], luTooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipPosition", required: false }] }], prTooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipPosition", required: false }] }], luTooltipWhenEllipsisInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipWhenEllipsis", required: false }] }], prTooltipWhenEllipsisInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipWhenEllipsis", required: false }] }], luTooltipAnchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipAnchor", required: false }] }], prTooltipAnchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipAnchor", required: false }] }], luTooltipTriggerAnchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "luTooltipTriggerAnchor", required: false }] }], prTooltipTriggerAnchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "prTooltipTriggerAnchor", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
592
664
|
|
|
593
665
|
/**
|
|
594
666
|
* @deprecated use `LuTooltipTriggerDirective` instead
|