diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..745b00b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +## v2.0.0 + +- К `_tooltip.$tooltip` добавлено свойство `_reference` для доступа к элементу, на котором был вызван `createTooltip` +- Для функций `show/hide` добавлен параметр `immediately` для мнгновенного открытия/закрытия всплывающей подсказки (`_tooltip.hide({ immediately: true })`) +- Добавлена опция `shiftPadding` для добавления отступов от краёв области видимости по осям x/y +- Добавлена опция `animation` для кастомизации анимации при открытии/закрытии всплывающей подсказки (для этого всё внутри `.tooltip` было обёрнуто в `.tooltip__root` и анимация применяется именно к этому блоку) +- Опция `_tooltip._options` переименована в `_tooltip.options` +- Оптимизция кода, исправление ошибок +- Доработки по README.md +- Доработки по .npmignore + +## v1.0.0 diff --git a/README.md b/README.md index 8a03202..c16c872 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ createTooltip(document.querySelector('button'), 'Подсказка'); import { createTooltip } from '@advdominion/tooltip'; createTooltip(document.querySelector('button'), 'Подсказка', { + animation: [ + [{ opacity: 0 }, { opacity: 1 }], + [{ opacity: 1 }, { opacity: 0 }], + ], appendTo: document.body, arrow: true, delay: [0, 0], @@ -37,6 +41,7 @@ createTooltip(document.querySelector('button'), 'Подсказка', { interactive: true, offset: [0, 8], placement: 'top', + shiftPadding: [8, 0], theme: 'light', trigger: 'mouseenter', virtialReference: undefined, @@ -76,8 +81,34 @@ createTooltip(document.querySelector('button'), 'Подсказка', { }); ``` +#### Свойства + +#### $tooltip + +DOM-элемент всплывающей подсказки (имеет свойство `_reference` для доступа к элементу, на котором был вызван `createTooltip`) + +#### options + +Текущие настройки + +#### isVisible + +Видимость всплывающей подсказки - `true`/`false` + #### Методы +##### show + +```js +document.querySelector('button')._tooltip.show(); +``` + +##### hide + +```js +document.querySelector('button')._tooltip.hide(); +``` + ##### setContent ```js @@ -96,6 +127,12 @@ document.querySelector('button')._tooltip.updateOptions({ placement: 'bottom' }) ``` +##### destroy + +```js +document.querySelector('button')._tooltip.destroy(); +``` + ### Стили ```scss @@ -113,6 +150,9 @@ $b: '.tooltip'; max-width: 300px; } + &__root { + } + &__arrow { #{$b}_theme_light & { background-color: white; diff --git a/index.js b/index.js index f4f42b2..c1537de 100644 --- a/index.js +++ b/index.js @@ -3,17 +3,27 @@ const roundByDPR = (value) => { return Math.round(value * dpr) / dpr; }; +const attributeToOption = (attribute) => { + attribute = attribute.replace('tooltip', ''); + return attribute.charAt(0).toLowerCase() + attribute.slice(1); +}; + export const createTooltip = ($el, content, options) => { options = { + animation: [ + [{ opacity: 0 }, { opacity: 1 }], + [{ opacity: 1 }, { opacity: 0 }], + ], appendTo: document.body, arrow: true, delay: [0, 0], duration: [0, 0], easing: ['linear', 'linear'], - hideOnClick: true, + hideOnClick: true, // Возможные значения: true, 'all', 'trigger' interactive: true, offset: [0, 8], placement: 'top', + shiftPadding: [8, 0], theme: 'light', trigger: 'mouseenter', virtialReference: undefined, @@ -21,46 +31,29 @@ export const createTooltip = ($el, content, options) => { ...options, }; - if ($el.dataset.tooltipArrow !== undefined) { - options.arrow = $el.dataset.tooltipArrow === 'true'; - } - - if ($el.dataset.tooltipHideOnClick !== undefined) { - switch ($el.dataset.tooltipHideOnClick) { - case 'all': - case 'toggle': { - options.hideOnClick = $el.dataset.tooltipHideOnClick; - break; - } - default: { - options.hideOnClick = $el.dataset.tooltipHideOnClick === 'true'; - } + const setOptionFromDataAttribute = (attribute) => { + if ($el.dataset[attribute] !== undefined) { + let value = $el.dataset[attribute]; + try { + value = JSON.parse($el.dataset[attribute]); + } catch {} + options[attributeToOption(attribute)] = value; } - } + }; - if ($el.dataset.tooltipInteractive !== undefined) { - options.interactive = $el.dataset.tooltipInteractive === 'true'; - } - - if ($el.dataset.tooltipOffset !== undefined) { - options.offset = JSON.parse($el.dataset.tooltipOffset); - } - - if ($el.dataset.tooltipPlacement !== undefined) { - options.placement = $el.dataset.tooltipPlacement; - } - - if ($el.dataset.tooltipTheme !== undefined) { - options.theme = $el.dataset.tooltipTheme; - } - - if ($el.dataset.tooltipTrigger !== undefined) { - options.trigger = $el.dataset.tooltipTrigger; - } - - if ($el.dataset.tooltipZIndex !== undefined) { - options.zIndex = $el.dataset.tooltipZIndex; - } + setOptionFromDataAttribute('tooltipAnimation'); + setOptionFromDataAttribute('tooltipArrow'); + setOptionFromDataAttribute('tooltipDelay'); + setOptionFromDataAttribute('tooltipDuration'); + setOptionFromDataAttribute('tooltipEasing'); + setOptionFromDataAttribute('tooltipHideOnClick'); + setOptionFromDataAttribute('tooltipInteractive'); + setOptionFromDataAttribute('tooltipOffset'); + setOptionFromDataAttribute('tooltipPlacement'); + setOptionFromDataAttribute('tooltipShiftPadding'); + setOptionFromDataAttribute('tooltipTheme'); + setOptionFromDataAttribute('tooltipTrigger'); + setOptionFromDataAttribute('tooltipZIndex'); let showTimeout; let hideTimeout; @@ -69,7 +62,7 @@ export const createTooltip = ($el, content, options) => { const listeners = []; $el._tooltip = { - _options: options, + options, isVisible: false, setContent(updatedContent) { if (updatedContent !== undefined) { @@ -159,13 +152,16 @@ export const createTooltip = ($el, content, options) => { options.onCreate($el._tooltip); } - $el._tooltip.show = async () => { + $el._tooltip.show = async (params = {}) => { + const { immediately } = params; + clearTimeout(hideTimeout); if (!$el._tooltip.$tooltip) { const { computePosition, offset, flip, shift, arrow } = await import('@floating-ui/dom'); $el._tooltip.$tooltip = document.createElement('div'); + $el._tooltip.$tooltip._reference = $el; $el._tooltip.updatePosition = async () => { const $arrow = $el._tooltip.$tooltip.querySelector('.tooltip__arrow'); @@ -180,7 +176,14 @@ export const createTooltip = ($el, content, options) => { crossAxis: options.offset[0], }), flip(), - shift(), + shift({ + padding: { + top: options.shiftPadding[1], + right: options.shiftPadding[0], + bottom: options.shiftPadding[1], + left: options.shiftPadding[0], + }, + }), arrow({ element: $arrow, padding: Number.parseInt( @@ -241,27 +244,29 @@ export const createTooltip = ($el, content, options) => { $el._tooltip.$tooltip.classList.add('tooltip', `tooltip_theme_${options.theme}`); Object.assign($el._tooltip.$tooltip.style, { zIndex: options.zIndex }); $el._tooltip.$tooltip.innerHTML = ` - ${ - options.interactive - ? ` -