app/components/primer/alpha/tooltip.js in primer_view_components-0.0.69 vs app/components/primer/alpha/tooltip.js in primer_view_components-0.0.70

- old
+ new

@@ -1,21 +1,20 @@ -var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { - if (!privateMap.has(receiver)) { - throw new TypeError("attempted to set private field on non-instance"); - } - privateMap.set(receiver, value); - return value; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; -var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { - if (!privateMap.has(receiver)) { - throw new TypeError("attempted to get private field on non-instance"); - } - return privateMap.get(receiver); +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; -var _abortController, _align, _side, _allowUpdatePosition; +var _TooltipElement_instances, _TooltipElement_abortController, _TooltipElement_align, _TooltipElement_side, _TooltipElement_allowUpdatePosition, _TooltipElement_adjustedAnchorAlignment, _TooltipElement_updatePosition; import { getAnchoredPosition } from '@primer/behaviors'; const TOOLTIP_OPEN_CLASS = 'tooltip-open'; +const TOOLTIP_ARROW_EDGE_OFFSET = 10; const DIRECTION_CLASSES = [ 'tooltip-n', 'tooltip-s', 'tooltip-e', 'tooltip-w', @@ -25,14 +24,15 @@ 'tooltip-sw' ]; class TooltipElement extends HTMLElement { constructor() { super(); - _abortController.set(this, void 0); - _align.set(this, 'center'); - _side.set(this, 'outside-bottom'); - _allowUpdatePosition.set(this, false); + _TooltipElement_instances.add(this); + _TooltipElement_abortController.set(this, void 0); + _TooltipElement_align.set(this, 'center'); + _TooltipElement_side.set(this, 'outside-bottom'); + _TooltipElement_allowUpdatePosition.set(this, false); const shadow = this.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <style> ${this.styles()} </style> @@ -58,11 +58,12 @@ background: var(--color-neutral-emphasis-plus); border-radius: 6px; opacity: 0; max-width: 250px; word-wrap: break-word; - white-space: normal + white-space: normal; + width: max-content; } :host:before{ position: absolute; z-index: 1000001; @@ -98,15 +99,19 @@ animation-timing-function: ease-in; animation-delay: .4s } :host(.tooltip-s):before, + :host(.tooltip-n):before { + right: 50%; + } + + :host(.tooltip-s):before, :host(.tooltip-se):before, :host(.tooltip-sw):before { - right: 50%; bottom: 100%; - margin-right: -6px; + margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px; border-bottom-color: var(--color-neutral-emphasis-plus) } :host(.tooltip-s):after, :host(.tooltip-se):after, @@ -116,12 +121,11 @@ :host(.tooltip-n):before, :host(.tooltip-ne):before, :host(.tooltip-nw):before { top: 100%; - right: 50%; - margin-right: -6px; + margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px; border-top-color: var(--color-neutral-emphasis-plus) } :host(.tooltip-n):after, :host(.tooltip-ne):after, @@ -129,17 +133,18 @@ top: 100% } :host(.tooltip-se):before, :host(.tooltip-ne):before { - right: auto + left: 0; + margin-left: ${TOOLTIP_ARROW_EDGE_OFFSET}px; } :host(.tooltip-sw):before, :host(.tooltip-nw):before { right: 0; - margin-right: 6px + margin-right: ${TOOLTIP_ARROW_EDGE_OFFSET}px; } :host(.tooltip-w):before { top: 50%; bottom: 50%; @@ -180,30 +185,30 @@ return this.ownerDocument.getElementById(this.htmlFor); } connectedCallback() { var _a; this.hidden = true; - __classPrivateFieldSet(this, _allowUpdatePosition, true); + __classPrivateFieldSet(this, _TooltipElement_allowUpdatePosition, true, "f"); if (!this.id) { this.id = `tooltip-${Date.now()}-${(Math.random() * 10000).toFixed(0)}`; } if (!this.control) return; this.setAttribute('role', 'tooltip'); - (_a = __classPrivateFieldGet(this, _abortController)) === null || _a === void 0 ? void 0 : _a.abort(); - __classPrivateFieldSet(this, _abortController, new AbortController()); - const { signal } = __classPrivateFieldGet(this, _abortController); + (_a = __classPrivateFieldGet(this, _TooltipElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort(); + __classPrivateFieldSet(this, _TooltipElement_abortController, new AbortController(), "f"); + const { signal } = __classPrivateFieldGet(this, _TooltipElement_abortController, "f"); this.addEventListener('mouseleave', this, { signal }); this.control.addEventListener('mouseenter', this, { signal }); this.control.addEventListener('mouseleave', this, { signal }); this.control.addEventListener('focus', this, { signal }); this.control.addEventListener('blur', this, { signal }); this.ownerDocument.addEventListener('keydown', this, { signal }); } disconnectedCallback() { var _a; - (_a = __classPrivateFieldGet(this, _abortController)) === null || _a === void 0 ? void 0 : _a.abort(); + (_a = __classPrivateFieldGet(this, _TooltipElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort(); } handleEvent(event) { if (!this.control) return; // Ensures that tooltip stays open when hovering between tooltip and element @@ -244,137 +249,132 @@ this.classList.add(TOOLTIP_OPEN_CLASS); for (const tooltip of this.ownerDocument.querySelectorAll(this.tagName)) { if (tooltip !== this) tooltip.hidden = true; } - this..call(this); + __classPrivateFieldGet(this, _TooltipElement_instances, "m", _TooltipElement_updatePosition).call(this); } } else if (name === 'data-direction') { this.classList.remove(...DIRECTION_CLASSES); const direction = this.direction; if (direction === 'n') { - __classPrivateFieldSet(this, _align, 'center'); - __classPrivateFieldSet(this, _side, 'outside-top'); + __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-top', "f"); } else if (direction === 'ne') { - __classPrivateFieldSet(this, _align, 'start'); - __classPrivateFieldSet(this, _side, 'outside-top'); + __classPrivateFieldSet(this, _TooltipElement_align, 'start', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-top', "f"); } else if (direction === 'e') { - __classPrivateFieldSet(this, _align, 'center'); - __classPrivateFieldSet(this, _side, 'outside-right'); + __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-right', "f"); } else if (direction === 'se') { - __classPrivateFieldSet(this, _align, 'start'); - __classPrivateFieldSet(this, _side, 'outside-bottom'); + __classPrivateFieldSet(this, _TooltipElement_align, 'start', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-bottom', "f"); } else if (direction === 's') { - __classPrivateFieldSet(this, _align, 'center'); - __classPrivateFieldSet(this, _side, 'outside-bottom'); + __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-bottom', "f"); } else if (direction === 'sw') { - __classPrivateFieldSet(this, _align, 'end'); - __classPrivateFieldSet(this, _side, 'outside-bottom'); + __classPrivateFieldSet(this, _TooltipElement_align, 'end', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-bottom', "f"); } else if (direction === 'w') { - __classPrivateFieldSet(this, _align, 'center'); - __classPrivateFieldSet(this, _side, 'outside-left'); + __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-left', "f"); } else if (direction === 'nw') { - __classPrivateFieldSet(this, _align, 'end'); - __classPrivateFieldSet(this, _side, 'outside-top'); + __classPrivateFieldSet(this, _TooltipElement_align, 'end', "f"); + __classPrivateFieldSet(this, _TooltipElement_side, 'outside-top', "f"); } } } - // `getAnchoredPosition` may calibrate `anchoredSide` but does not recalibrate `align`. - // Therefore, we need to determine which `align` is best based on the initial `getAnchoredPosition` calcluation. - // Related: https://github.com/primer/behaviors/issues/63 - (anchorSide) { - if (!this.control) - return; - const tooltipPosition = this.getBoundingClientRect(); - const targetPosition = this.control.getBoundingClientRect(); - const tooltipWidth = tooltipPosition.width; - const tooltipCenter = tooltipPosition.left + tooltipWidth / 2; - const targetCenter = targetPosition.x + targetPosition.width / 2; - if (Math.abs(tooltipCenter - targetCenter) < 2 || anchorSide === 'outside-left' || anchorSide === 'outside-right') { - return 'center'; - } - else if (tooltipPosition.left === targetPosition.left) { +} +_TooltipElement_abortController = new WeakMap(), _TooltipElement_align = new WeakMap(), _TooltipElement_side = new WeakMap(), _TooltipElement_allowUpdatePosition = new WeakMap(), _TooltipElement_instances = new WeakSet(), _TooltipElement_adjustedAnchorAlignment = function _TooltipElement_adjustedAnchorAlignment(anchorSide) { + if (!this.control) + return; + const tooltipPosition = this.getBoundingClientRect(); + const targetPosition = this.control.getBoundingClientRect(); + const tooltipWidth = tooltipPosition.width; + const tooltipCenter = tooltipPosition.left + tooltipWidth / 2; + const targetCenter = targetPosition.x + targetPosition.width / 2; + if (Math.abs(tooltipCenter - targetCenter) < 2 || anchorSide === 'outside-left' || anchorSide === 'outside-right') { + return 'center'; + } + else if (tooltipPosition.left === targetPosition.left) { + return 'start'; + } + else if (tooltipPosition.right === targetPosition.right) { + return 'end'; + } + else if (tooltipCenter < targetCenter) { + if (tooltipPosition.left === 0) return 'start'; - } - else if (tooltipPosition.right === targetPosition.right) { + return 'end'; + } + else { + if (tooltipPosition.right === 0) return 'end'; + return 'start'; + } +}, _TooltipElement_updatePosition = function _TooltipElement_updatePosition() { + if (!this.control) + return; + if (!__classPrivateFieldGet(this, _TooltipElement_allowUpdatePosition, "f") || this.hidden) + return; + const TOOLTIP_OFFSET = 10; + this.style.left = `0px`; // Ensures we have reliable tooltip width in `getAnchoredPosition` + let position = getAnchoredPosition(this, this.control, { + side: __classPrivateFieldGet(this, _TooltipElement_side, "f"), + align: __classPrivateFieldGet(this, _TooltipElement_align, "f"), + anchorOffset: TOOLTIP_OFFSET + }); + let anchorSide = position.anchorSide; + // We need to set tooltip position in order to determine ideal align. + this.style.top = `${position.top}px`; + this.style.left = `${position.left}px`; + let direction = 's'; + const align = __classPrivateFieldGet(this, _TooltipElement_instances, "m", _TooltipElement_adjustedAnchorAlignment).call(this, anchorSide); + if (!align) + return; + this.style.left = `0px`; // Reset tooltip position again to ensure accurate width in `getAnchoredPosition` + position = getAnchoredPosition(this, this.control, { side: anchorSide, align, anchorOffset: TOOLTIP_OFFSET }); + anchorSide = position.anchorSide; + this.style.top = `${position.top}px`; + this.style.left = `${position.left}px`; + if (anchorSide === 'outside-left') { + direction = 'w'; + } + else if (anchorSide === 'outside-right') { + direction = 'e'; + } + else if (anchorSide === 'outside-top') { + if (align === 'center') { + direction = 'n'; } - else if (tooltipCenter < targetCenter) { - if (tooltipPosition.left === 0) - return 'start'; - return 'end'; + else if (align === 'start') { + direction = 'ne'; } else { - if (tooltipPosition.right === 0) - return 'end'; - return 'start'; + direction = 'nw'; } } - () { - if (!this.control) - return; - if (!__classPrivateFieldGet(this, _allowUpdatePosition) || this.hidden) - return; - const TOOLTIP_OFFSET = 10; - this.style.left = `0px`; // Ensures we have reliable tooltip width in `getAnchoredPosition` - let position = getAnchoredPosition(this, this.control, { - side: __classPrivateFieldGet(this, _side), - align: __classPrivateFieldGet(this, _align), - anchorOffset: TOOLTIP_OFFSET - }); - let anchorSide = position.anchorSide; - // We need to set tooltip position in order to determine ideal align. - this.style.top = `${position.top}px`; - this.style.left = `${position.left}px`; - let direction = 's'; - const align = this..call(this, anchorSide); - if (!align) - return; - this.style.left = `0px`; // Reset tooltip position again to ensure accurate width in `getAnchoredPosition` - position = getAnchoredPosition(this, this.control, { side: anchorSide, align, anchorOffset: TOOLTIP_OFFSET }); - anchorSide = position.anchorSide; - this.style.top = `${position.top}px`; - this.style.left = `${position.left}px`; - if (anchorSide === 'outside-left') { - direction = 'w'; + else { + if (align === 'center') { + direction = 's'; } - else if (anchorSide === 'outside-right') { - direction = 'e'; + else if (align === 'start') { + direction = 'se'; } - else if (anchorSide === 'outside-top') { - if (align === 'center') { - direction = 'n'; - } - else if (align === 'start') { - direction = 'ne'; - } - else { - direction = 'nw'; - } - } else { - if (align === 'center') { - direction = 's'; - } - else if (align === 'start') { - direction = 'se'; - } - else { - direction = 'sw'; - } + direction = 'sw'; } - this.classList.add(`tooltip-${direction}`); } -} -_abortController = new WeakMap(), _align = new WeakMap(), _side = new WeakMap(), _allowUpdatePosition = new WeakMap(); + this.classList.add(`tooltip-${direction}`); +}; TooltipElement.observedAttributes = ['data-type', 'data-direction', 'id', 'hidden']; if (!window.customElements.get('tool-tip')) { window.TooltipElement = TooltipElement; window.customElements.define('tool-tip', TooltipElement); }