UNPKG

@govbr-ds/webcomponents

Version:

Biblioteca de Web Components baseado no GovBR-DS

120 lines (119 loc) 5.63 kB
/*! * Construído por SERPRO * © https://serpro.gov.br/ - MIT License. */ import { __awaiter } from "tslib"; import { arrow, autoUpdate, computePosition, flip, hide, offset, shift } from "@floating-ui/dom"; /** * FloatingUIManager é uma classe utilitária que gerencia o posicionamento de elementos flutuantes * como tooltips ou popovers em relação a um elemento de disparo (trigger). * Ela utiliza a biblioteca Floating UI para calcular posições e lidar com atualizações. */ export class FloatingUIManager { constructor(options) { var _a; this.triggerElement = options.triggerElement; this.contentElement = options.contentElement; this.arrowElement = options.arrowElement; this.placement = (_a = options.placement) !== null && _a !== void 0 ? _a : 'top'; this.onUpdate = options.onUpdate; } /** * Inicia o gerenciador Floating UI configurando a atualização automática da posição. */ start() { this.cleanupAutoUpdate = autoUpdate(this.triggerElement, this.contentElement, () => this.updatePosition()); } /** * Para o gerenciador Floating UI e limpa os recursos utilizados. */ stop() { var _a; (_a = this.cleanupAutoUpdate) === null || _a === void 0 ? void 0 : _a.call(this); } /** * Atualiza a posição do elemento flutuante com base no elemento disparador e no elemento de conteúdo. * Esta função é chamada automaticamente quando o gerenciador está ativo. * Ela calcula a nova posição usando a biblioteca Floating UI e aplica as transformações necessárias. * Também atualiza a posição da seta, se fornecida. * Além disso, define o atributo de dados `data-placement` no elemento de conteúdo para refletir a posição atual. * @returns {Promise<void>} Uma promessa que resolve quando a posição é atualizada. */ updatePosition() { return __awaiter(this, void 0, void 0, function* () { var _a; const data = yield computePosition(this.triggerElement, this.contentElement, { placement: this.placement, middleware: this.buildMiddleware(), }); this.updateTooltipPosition(data); this.updateArrowPosition(data); this.setPlacementDataAttribute(data); (_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.call(this, data); }); } /** * Constrói os middlewares necessários para o Floating UI. * Esses middlewares são usados para ajustar o posicionamento do elemento flutuante, * incluindo offset, flip, shift e hide. Se uma seta for fornecida, o middleware de seta também é adicionado. * @returns {Middleware[]} Retorna um array de middlewares configurados para o Floating UI. */ buildMiddleware() { const middleware = [offset(8), flip(), shift({ padding: 5 }), hide()]; if (this.arrowElement != null) { middleware.push(arrow({ element: this.arrowElement })); } return middleware; } /** * Adiciona o estilo necessário para posicionar o tooltip com base nas coordenadas fornecidas. * Esta função é chamada após o cálculo da posição do tooltip. * Ela aplica as propriedades CSS `left` e `top` ao elemento de conteúdo do tooltip. * @param data Contém as coordenadas x e y para posicionar o tooltip. */ updateTooltipPosition(data) { const { x, y } = data; Object.assign(this.contentElement.style, { left: `${x}px`, top: `${y}px`, }); } /** * Adiciona o estilo necessário para posicionar a seta do tooltip com base nos dados de middleware. * Esta função é chamada após o cálculo da posição do tooltip. * Ela aplica as propriedades CSS `left`, `top`, `right`, `bottom` e a posição estática da seta. * A posição estática é determinada com base na colocação do tooltip (top, right, bottom, left). * Se a seta não estiver presente ou os dados de middleware não contiverem informações sobre a seta, nada será feito. * @param data Contém a posição da seta e os dados de middleware. */ updateArrowPosition(data) { if (this.arrowElement == null || data.middlewareData.arrow == null) return; const { x: arrowX, y: arrowY } = data.middlewareData.arrow; const basePlacement = data.placement.split('-')[0]; const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right', }[basePlacement]; Object.assign(this.arrowElement.style, { left: arrowX != null ? `${arrowX}px` : '', top: arrowY != null ? `${arrowY}px` : '', right: '', bottom: '', [staticSide]: '-4px', }); } /** * Define o atributo de dados `data-placement` no elemento de conteúdo. * Este atributo é usado para indicar a posição atual do tooltip ou popover. * Ele é útil para fins de acessibilidade e para permitir que estilos CSS sejam aplicados com base na posição. * @param data Objeto contendo a propriedade `placement` que define a posição do tooltip ou popover. * A propriedade `placement` deve ser uma string representando a posição, como 'top', 'bottom', 'left', 'right', etc. */ setPlacementDataAttribute(data) { this.contentElement.setAttribute('data-placement', data.placement); } } //# sourceMappingURL=floating-ui.js.map