UNPKG

uicore-ts

Version:

UICore is a library to build native-like user interfaces using pure Typescript. No HTML is needed at all. Components are described as TS classes and all user interactions are handled explicitly. This library is strongly inspired by the UIKit framework tha

197 lines (196 loc) 6.77 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var UITooltip_exports = {}; __export(UITooltip_exports, { UITooltip: () => UITooltip }); module.exports = __toCommonJS(UITooltip_exports); var import_UIColor = require("./UIColor"); var import_UICore = require("./UICore"); var import_UIView = require("./UIView"); const _UITooltip = class { constructor() { this.offsetX = 14; this.offsetY = 20; this.maxWidth = 320; this._isVisible = false; this._mouseX = 0; this._mouseY = 0; this._isInitialized = false; this._attachedHandlers = /* @__PURE__ */ new WeakMap(); const { contentView, labelElement } = this.createContentView(); this.contentView = contentView; this._labelElement = labelElement; const element = this.contentView.viewHTMLElement; element.style.position = "fixed"; element.style.pointerEvents = "none"; element.style.display = "none"; this.contentView.calculateAndSetViewFrame = () => { this._recalculateFrame(); }; this.applyStyles(); } createContentView() { var _a, _b; const labelElement = document.createElement("span"); labelElement.style.display = "block"; labelElement.style.whiteSpace = "pre-wrap"; labelElement.style.wordBreak = "break-word"; labelElement.style.lineHeight = "1.4"; labelElement.style.color = "#ffffff"; labelElement.style.fontSize = "12px"; labelElement.style.fontWeight = "400"; const paddingPx = `${((_b = (_a = import_UICore.UICore.main) == null ? void 0 : _a.paddingLength) != null ? _b : 16) * 0.5}px`; labelElement.style.padding = paddingPx; labelElement.style.boxSizing = "border-box"; const contentView = new import_UIView.UIView(); contentView.configureWithObject({ backgroundColor: new import_UIColor.UIColor("rgba(30, 30, 40, 0.96)"), style: { borderRadius: "5px", boxShadow: "0 4px 12px rgba(0,0,0,0.25)" } }); contentView.viewHTMLElement.appendChild(labelElement); return { contentView, labelElement }; } applyStyles() { } setText(text) { if (this._labelElement) { this._labelElement.textContent = text; } } measureContentSize() { if (this._labelElement) { return this._measureHTMLLabelSize(); } const height = this.contentView.intrinsicContentHeight(this.maxWidth); const width = Math.min(this.contentView.intrinsicContentWidth(height), this.maxWidth); return { width, height }; } _measureHTMLLabelSize() { const label = this._labelElement; const prevMaxWidth = label.style.maxWidth; const prevWidth = label.style.width; let wasDetached = false; if (!label.isConnected) { document.body.appendChild(label); wasDetached = true; } label.style.maxWidth = `${this.maxWidth}px`; label.style.width = ""; const wrappedHeight = label.scrollHeight; label.style.maxWidth = `${this.maxWidth}px`; label.style.width = "fit-content"; const naturalWidth = label.scrollWidth; if (wasDetached) { document.body.removeChild(label); } label.style.maxWidth = prevMaxWidth; label.style.width = prevWidth; return { width: Math.min(Math.ceil(naturalWidth), this.maxWidth), height: wrappedHeight }; } get core() { return import_UICore.UICore.main; } _recalculateFrame() { const { width, height } = this.measureContentSize(); const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const margin = 8; let left = this._mouseX + this.offsetX; let top = this._mouseY + this.offsetY; if (left + width > viewportWidth - margin) { left = this._mouseX - width - this.offsetX; } if (top + height > viewportHeight - margin) { top = this._mouseY - height - this.offsetY * 0.5; } left = Math.max(margin, left); top = Math.max(margin, top); this.contentView.setFrame( this.contentView.frame.rectangleWithX(Math.round(left)).rectangleWithY(Math.round(top)).rectangleWithWidth(width).rectangleWithHeight(height), 99999 ); } _ensureInitialized() { if (this._isInitialized) { return; } this._isInitialized = true; document.body.appendChild(this.contentView.viewHTMLElement); window.addEventListener("mousemove", (event) => { this._mouseX = event.clientX; this._mouseY = event.clientY; if (this._isVisible) { this.contentView.calculateAndSetViewFrame(); } }, { passive: true }); } show(text) { this._ensureInitialized(); this.setText(text); this.contentView.viewHTMLElement.style.display = "block"; if (!this._labelElement) { this.contentView.setNeedsLayout(); import_UIView.UIView.layoutViewsIfNeeded(); } this._isVisible = true; this.contentView.calculateAndSetViewFrame(); } hide() { this._isVisible = false; this.contentView.viewHTMLElement.style.display = "none"; } attach(view, text) { this.detach(view); const enterHandler = (_sender, _event) => { this.show(text); }; const leaveHandler = (_sender, _event) => { this.hide(); }; view.controlEventTargetAccumulator.PointerHover = enterHandler; view.controlEventTargetAccumulator.PointerLeave = leaveHandler; this._attachedHandlers.set(view, { enter: enterHandler, leave: leaveHandler }); } detach(view) { const handlers = this._attachedHandlers.get(view); if (!handlers) { return; } view.removeTargetForControlEvent(import_UIView.UIView.controlEvent.PointerHover, handlers.enter); view.removeTargetForControlEvent(import_UIView.UIView.controlEvent.PointerLeave, handlers.leave); this._attachedHandlers.delete(view); if (this._isVisible) { this.hide(); } } }; let UITooltip = _UITooltip; UITooltip.sharedInstance = new _UITooltip(); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { UITooltip }); //# sourceMappingURL=UITooltip.js.map