312 lines
13 KiB
Markdown
312 lines
13 KiB
Markdown
# tooltip
|
|
|
|
## Требования
|
|
|
|
- [Floating UI](https://floating-ui.com)
|
|
|
|
## Подключение и настройка
|
|
|
|
### HTML
|
|
|
|
```html
|
|
<button type="button">Кнопка</button>
|
|
```
|
|
|
|
### JS
|
|
|
|
#### Минимальные настройки
|
|
|
|
```js
|
|
import { createTooltip } from '@advdominion/tooltip';
|
|
|
|
createTooltip(document.querySelector('button'), 'Подсказка');
|
|
```
|
|
|
|
#### Все настройки со значениями по умолчанию
|
|
|
|
```js
|
|
import { createTooltip } from '@advdominion/tooltip';
|
|
|
|
createTooltip(document.querySelector('button'), 'Подсказка', {
|
|
animation: [
|
|
[{ opacity: 0 }, { opacity: 1 }],
|
|
[{ opacity: 1 }, { opacity: 0 }],
|
|
],
|
|
appendTo: document.body,
|
|
arrow: { active: true, centered: false, padding: undefined },
|
|
delay: [0, 0],
|
|
duration: [0, 0],
|
|
easing: ['linear', 'linear'],
|
|
flipPadding: 0,
|
|
hideOnClick: true,
|
|
interactive: true,
|
|
offset: [0, 8],
|
|
placement: 'top',
|
|
shiftPadding: [8, 0],
|
|
theme: 'light',
|
|
trigger: 'mouseenter click',
|
|
virtualReference: undefined,
|
|
zIndex: '',
|
|
// Callback-функции, по умолчанию не заданы
|
|
onCreate(instance) {},
|
|
onMount(instance) {},
|
|
onShow(instance) {},
|
|
onShown(instance) {},
|
|
onHide(instance) {},
|
|
onHidden(instance) {},
|
|
});
|
|
```
|
|
|
|
Любую настройку можно задать через data-атрибут: имя опции в kebab-case с префиксом `data-tooltip-`. Значение парсится как JSON, а если разобрать не удалось — используется как строка.
|
|
|
|
```html
|
|
<button type="button" data-tooltip-placement="bottom" data-tooltip-offset="[0, 12]">Кнопка</button>
|
|
```
|
|
|
|
#### animation
|
|
|
|
Две последовательности keyframes для `Element.animate`: первая проигрывается при появлении, вторая — при скрытии.
|
|
|
|
```js
|
|
createTooltip(document.querySelector('button'), 'Подсказка', {
|
|
animation: [
|
|
[
|
|
{ opacity: 0, transform: 'translateY(-5px)' },
|
|
{ opacity: 1, transform: 'translateY(0)' },
|
|
],
|
|
[
|
|
{ opacity: 1, transform: 'translateY(0)' },
|
|
{ opacity: 0, transform: 'translateY(-5px)' },
|
|
],
|
|
],
|
|
});
|
|
```
|
|
|
|
#### appendTo
|
|
|
|
Элемент, в который вставляется подсказка перед показом. По умолчанию `document.body`. Значение `'parent'` вставляет подсказку в родителя опорного элемента — это нужно, когда её обрезает или перекрывает контейнер.
|
|
|
|
#### arrow
|
|
|
|
Настройка отображения и позиционирования стрелки. Поддерживает булево значение (`true`/`false`) для обратной совместимости либо объект:
|
|
|
|
- `active` (`true`) — показывать ли стрелку. Эквивалент `arrow: true`/`arrow: false`.
|
|
- `centered` (`false`) — фиксировать стрелку по центру всплывающей подсказки, вместо того чтобы следовать за центром элемента, который её вызывает. Полезно, когда подсказка прижата к краю области видимости и стрелка смещается при прокрутке.
|
|
- `padding` (`undefined`) — отступ стрелки от краёв всплывающей подсказки. По умолчанию рассчитывается автоматически исходя из размера стрелки, чтобы её повёрнутые под 45° углы не выходили за границы подсказки.
|
|
|
|
```js
|
|
createTooltip(document.querySelector('button'), 'Подсказка', {
|
|
arrow: { active: true, centered: true },
|
|
});
|
|
```
|
|
|
|
#### delay
|
|
|
|
Задержка перед появлением и перед скрытием в миллисекундах: `[появление, скрытие]`. Методы `show({ immediately: true })` и `hide({ immediately: true })` отключают задержку и анимацию.
|
|
|
|
#### duration
|
|
|
|
Длительность анимации появления и скрытия в миллисекундах: `[появление, скрытие]`.
|
|
|
|
#### easing
|
|
|
|
Функция плавности анимации появления и скрытия: `[появление, скрытие]`. Принимает значения CSS, например `ease-out` или `cubic-bezier(0.4, 0, 0.2, 1)`.
|
|
|
|
#### flipPadding
|
|
|
|
Минимальный зазор между подсказкой и краем области видимости, при котором подсказка переворачивается на противоположную сторону. По умолчанию `0`: переворот происходит, только если подсказка не помещается целиком.
|
|
|
|
Переворот наступает, когда подсказка, её зазор `offset` и `flipPadding` вместе не помещаются с выбранной стороны. Например, при `flipPadding: 60` подсказка над элементом перевернётся вниз, если сверху останется меньше 60 px свободного места.
|
|
|
|
Значение передаётся в middleware `flip` из Floating UI: число либо объект со сторонами `top`, `right`, `bottom`, `left`.
|
|
|
|
```js
|
|
createTooltip(document.querySelector('button'), 'Подсказка', {
|
|
flipPadding: 60,
|
|
});
|
|
```
|
|
|
|
Так же настраивается через data-атрибут:
|
|
|
|
```html
|
|
<button type="button" data-tooltip-flip-padding="60">Кнопка</button>
|
|
```
|
|
|
|
#### hideOnClick
|
|
|
|
- `true` (по умолчанию) — всплывающая подсказка скрывается при клике по любому элементу на странице (**кроме** самой всплывающей подсказки).
|
|
- `'all'` — всплывающая подсказка скрывается при клике по любому элементу на странице (**включая** саму всплывающую подсказку).
|
|
- `'toggle'` — всплывающая подсказка скрывается только при клике по элементу, который её вызывает.
|
|
|
|
Настройка работает только с `trigger`, включающим `click` или `manual`.
|
|
|
|
#### interactive
|
|
|
|
`true` (по умолчанию) — курсор можно перевести с элемента на подсказку и взаимодействовать с её содержимым. Невидимая зона перекрывает зазор `offset` между элементом и подсказкой, чтобы подсказка не скрылась по пути курсора.
|
|
|
|
`false` — подсказка скрывается сразу, как только курсор уходит с элемента.
|
|
|
|
#### offset
|
|
|
|
Зазор между элементом и подсказкой: `[поперёк основной оси, вдоль основной оси]`. Для `top` и `bottom` первое значение сдвигает подсказку по горизонтали, второе задаёт зазор по вертикали. По умолчанию `[0, 8]` — 8 px между элементом и подсказкой.
|
|
|
|
#### placement
|
|
|
|
Сторона размещения: `top`, `right`, `bottom`, `left`. Выравнивание задаётся суффиксом `-start` или `-end`, например `bottom-start`. Если места с выбранной стороны не хватает, подсказка переворачивается (см. `flipPadding`).
|
|
|
|
#### shiftPadding
|
|
|
|
Отступ от края области видимости, на который подсказка сдвигается вдоль оси, чтобы полностью поместиться на экране: `[по горизонтали, по вертикали]`. Для `top` и `bottom` работает по горизонтали, для `left` и `right` — по вертикали.
|
|
|
|
По умолчанию `[8, 0]`. Пример с отступом 12 px от краёв экрана на мобильных:
|
|
|
|
```js
|
|
createTooltip(document.querySelector('button'), 'Подсказка', {
|
|
shiftPadding: [12, 0],
|
|
});
|
|
```
|
|
|
|
#### theme
|
|
|
|
Тема оформления. Значение подставляется в класс `tooltip_theme_<theme>` — стили для каждой темы задаёт потребитель. По умолчанию `light`.
|
|
|
|
#### trigger
|
|
|
|
События, по которым показывается и скрывается подсказка: строка со списком через пробел. По умолчанию `mouseenter click`.
|
|
|
|
- `mouseenter` — по наведению курсора (только мышь);
|
|
- `click` — по клику;
|
|
- `focus` — по получению фокуса;
|
|
- `blur` — скрытие по потере фокуса;
|
|
- `manual` — без обработчиков: показ и скрытие только через `show()` и `hide()`.
|
|
|
|
```js
|
|
createTooltip(document.querySelector('button'), 'Подсказка', {
|
|
trigger: 'click',
|
|
});
|
|
```
|
|
|
|
#### virtualReference
|
|
|
|
Настройка используется для кастомного позиционирования, ожидает объект с методом `getBoundingClientRect`.
|
|
|
|
Например, позиционирование всплывающей подсказки относительно виртуального элемента размером 100×50, который располагается в левой верхней точке экрана:
|
|
|
|
```js
|
|
createTooltip(document.querySelector('button'), 'Подсказка', {
|
|
virtualReference: {
|
|
getBoundingClientRect() {
|
|
return {
|
|
x: 0,
|
|
y: 0,
|
|
top: 0,
|
|
left: 0,
|
|
bottom: 50,
|
|
right: 100,
|
|
width: 100,
|
|
height: 50,
|
|
};
|
|
},
|
|
},
|
|
});
|
|
```
|
|
|
|
#### zIndex
|
|
|
|
Значение для свойства `z-index` подсказки. По умолчанию пустая строка — `z-index` не задаётся, работает значение из CSS.
|
|
|
|
#### Колбэки
|
|
|
|
Каждый колбэк получает экземпляр подсказки (`instance` — то же, что `$el._tooltip`).
|
|
|
|
- `onCreate` — после создания экземпляра, до первого показа. Здесь уже доступны `show()` и `hide()`.
|
|
- `onMount` — при первом показе, после создания DOM подсказки и до её вставки в документ. Удобно для инициализации вложенных компонентов.
|
|
- `onShow` — после вставки в документ, перед анимацией появления.
|
|
- `onShown` — после анимации появления.
|
|
- `onHide` — перед анимацией скрытия.
|
|
- `onHidden` — после анимации скрытия, когда подсказка уже удалена из документа.
|
|
|
|
### Свойства
|
|
|
|
#### $tooltip
|
|
|
|
DOM-элемент всплывающей подсказки (имеет свойство `_reference` для доступа к элементу, на котором был вызван `createTooltip`)
|
|
|
|
#### options
|
|
|
|
Текущие настройки
|
|
|
|
#### isVisible
|
|
|
|
Видимость всплывающей подсказки - `true`/`false`
|
|
|
|
### Методы
|
|
|
|
#### show
|
|
|
|
```js
|
|
document.querySelector('button')._tooltip.show();
|
|
```
|
|
|
|
#### hide
|
|
|
|
```js
|
|
document.querySelector('button')._tooltip.hide();
|
|
```
|
|
|
|
#### setContent
|
|
|
|
```js
|
|
document.querySelector('button')._tooltip.setContent('Новая подсказка');
|
|
```
|
|
|
|
#### updateOptions
|
|
|
|
```js
|
|
document.querySelector('button')._tooltip.updateOptions({ placement: 'bottom' });
|
|
```
|
|
|
|
#### destroy
|
|
|
|
```js
|
|
document.querySelector('button')._tooltip.destroy();
|
|
```
|
|
|
|
### Стили
|
|
|
|
```scss
|
|
$b: '.tooltip';
|
|
|
|
#{$b} {
|
|
left: 0;
|
|
max-width: calc(100vw - 32px);
|
|
position: absolute;
|
|
top: 0;
|
|
width: max-content;
|
|
will-change: transform;
|
|
z-index: 200;
|
|
|
|
@media (min-width: 900px) {
|
|
max-width: 300px;
|
|
}
|
|
|
|
&__root {
|
|
}
|
|
|
|
&__arrow {
|
|
#{$b}_theme_light & {
|
|
background-color: white;
|
|
height: 8px;
|
|
width: 8px;
|
|
}
|
|
}
|
|
|
|
&__container {
|
|
#{$b}_theme_light & {
|
|
background-color: white;
|
|
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.2);
|
|
}
|
|
}
|
|
}
|
|
```
|