@formixru/b2b-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CONTRIBUTING.md +61 -0
  2. package/README.md +30 -0
  3. package/package.json +110 -0
  4. package/src/base.scss +89 -0
  5. package/src/components/action-list/index.scss +38 -0
  6. package/src/components/banner/index.scss +30 -0
  7. package/src/components/breadcrumbs/index.js +8 -0
  8. package/src/components/breadcrumbs/index.scss +55 -0
  9. package/src/components/button/index.scss +223 -0
  10. package/src/components/checkbox/index.scss +94 -0
  11. package/src/components/color-input/index.scss +88 -0
  12. package/src/components/color-input/index.vue +156 -0
  13. package/src/components/date-input/index.scss +126 -0
  14. package/src/components/date-input/index.vue +240 -0
  15. package/src/components/delete-all/index.scss +44 -0
  16. package/src/components/dialog/index.js +221 -0
  17. package/src/components/dialog/index.scss +198 -0
  18. package/src/components/empty-list/index.scss +97 -0
  19. package/src/components/file-input/index.scss +119 -0
  20. package/src/components/file-input/index.vue +333 -0
  21. package/src/components/font-input/index.scss +47 -0
  22. package/src/components/font-input/index.vue +154 -0
  23. package/src/components/form/index.js +228 -0
  24. package/src/components/form/index.scss +398 -0
  25. package/src/components/header-announcement/index.scss +48 -0
  26. package/src/components/input/index.js +85 -0
  27. package/src/components/input/index.scss +87 -0
  28. package/src/components/link/index.scss +266 -0
  29. package/src/components/loader/index.js +65 -0
  30. package/src/components/loader/index.scss +99 -0
  31. package/src/components/nobr/index.scss +5 -0
  32. package/src/components/overlay/index.js +82 -0
  33. package/src/components/overlay/index.scss +29 -0
  34. package/src/components/pagination/index.scss +59 -0
  35. package/src/components/pagination-group/index.js +5 -0
  36. package/src/components/pagination-group/index.scss +86 -0
  37. package/src/components/quantity-input/index.scss +179 -0
  38. package/src/components/quantity-input/index.vue +141 -0
  39. package/src/components/radio/index.scss +80 -0
  40. package/src/components/radio-list/index.scss +79 -0
  41. package/src/components/range-input/index.scss +109 -0
  42. package/src/components/range-input/index.vue +185 -0
  43. package/src/components/rating-input/index.js +32 -0
  44. package/src/components/rating-input/index.scss +36 -0
  45. package/src/components/select/index.js +6 -0
  46. package/src/components/select/index.scss +84 -0
  47. package/src/components/sidebar/index.js +174 -0
  48. package/src/components/sidebar/index.scss +398 -0
  49. package/src/components/simple-page/index.scss +32 -0
  50. package/src/components/slider-nav/index.scss +82 -0
  51. package/src/components/slider-pagination/index.scss +130 -0
  52. package/src/components/spinner/index.scss +35 -0
  53. package/src/components/sr-only/index.scss +25 -0
  54. package/src/components/steps/index.scss +155 -0
  55. package/src/components/suggest-input/index.scss +141 -0
  56. package/src/components/suggest-input/index.vue +324 -0
  57. package/src/components/tabs/index.js +192 -0
  58. package/src/components/tabs/index.scss +137 -0
  59. package/src/components/time-select/index.scss +27 -0
  60. package/src/components/toggle/index.scss +76 -0
  61. package/src/components/tooltip/index.js +69 -0
  62. package/src/components/tooltip/index.scss +112 -0
  63. package/src/components/total/index.scss +162 -0
  64. package/src/components/warning-message/index.scss +170 -0
  65. package/src/components/warning-message/index.vue +94 -0
  66. package/src/components/wysiwyg/index.scss +344 -0
  67. package/src/helpers/css-var.js +8 -0
  68. package/src/helpers/error-handler.js +61 -0
  69. package/src/helpers/get-smart-captcha.js +7 -0
  70. package/src/helpers/is-in-viewport.js +10 -0
  71. package/src/helpers/mm.js +52 -0
  72. package/src/helpers/scroll-to.js +21 -0
  73. package/src/variables.scss +1295 -0
@@ -0,0 +1,192 @@
1
+ /* globals BX */
2
+
3
+ import { cssVar } from '../../helpers/css-var.js';
4
+ import { errorHandler } from '../../helpers/error-handler.js';
5
+ import { isInViewport } from '../../helpers/is-in-viewport.js';
6
+ import { scrollTo } from '../../helpers/scroll-to.js';
7
+ import { hide as hideLoader, show as showLoader } from '../loader/index.js';
8
+
9
+ const setLeftWidth = async ($line, $el) => {
10
+ const $label = $el.querySelector('.tabs__label');
11
+ const styles = {
12
+ width: $label.getBoundingClientRect().width,
13
+ left: $label.offsetLeft,
14
+ };
15
+ await $line.animate([{ transform: `translateX(${styles.left}px)`, width: `${styles.width}px` }], {
16
+ duration: cssVar('--duration-effect-s'),
17
+ easing: cssVar('--easing-standard'),
18
+ fill: 'forwards',
19
+ }).finished;
20
+ };
21
+
22
+ export const setInitLineStyles = ($b) => {
23
+ const $nav = $b.querySelector('.tabs__nav');
24
+ const $item = $nav.querySelectorAll('.tabs__item');
25
+ const $line = $nav.querySelector('.tabs__line');
26
+
27
+ const $el = [...$item].find((el) => {
28
+ return el.disabled || (el.tagName !== 'BUTTON' && !el.href);
29
+ });
30
+
31
+ setLeftWidth($line, $el);
32
+ // Прокручиваем до нужного таба
33
+ if ($nav.swiper) {
34
+ $nav.swiper.slideTo([...$item].indexOf($el));
35
+ }
36
+ };
37
+
38
+ const initTabsContent = ($b) => {
39
+ try {
40
+ window.__FORMIX__TABS__INIT_CONTENT($b);
41
+ } catch {
42
+ console.warn('Функция __FORMIX__TABS__INIT_CONTENT не установлена');
43
+ }
44
+ };
45
+
46
+ export const init = async ($b) => {
47
+ const $nav = $b.querySelector('.tabs__nav');
48
+ const $list = $nav.querySelector('.tabs__list');
49
+ const $item = $nav.querySelectorAll('.tabs__item');
50
+ const $line = $nav.querySelector('.tabs__line');
51
+ const $content = $b.querySelectorAll('.tabs__content');
52
+
53
+ // Переключаем табы и меняем стили для линии
54
+ const handleItemClick = async (e) => {
55
+ const $el = e.currentTarget;
56
+ const index = [...$item].indexOf($el);
57
+ if ($el.tagName === 'BUTTON') {
58
+ if ($el.dataset.tabsFetch && $content[index].innerHTML.trim() === '') {
59
+ showLoader();
60
+ try {
61
+ const response = await fetch($el.dataset.tabsFetch, {
62
+ method: 'GET',
63
+ headers: {
64
+ 'X-Requested-With': 'XMLHttpRequest',
65
+ 'X-Session-Id': BX.message('bitrix_sessid'),
66
+ },
67
+ });
68
+ if (!response.ok) {
69
+ throw response;
70
+ }
71
+ const data = await response.text();
72
+ hideLoader();
73
+ // Вставляем полученный HTML
74
+ $content[index].innerHTML = data;
75
+ // Переключаем таб
76
+ for (const i of $item) i.disabled = false;
77
+ $el.disabled = true;
78
+ for (const [i, c] of $content.entries()) {
79
+ if (i === index) {
80
+ c.hidden = false;
81
+ for (const swiperEl of c.querySelectorAll('.swiper')) {
82
+ if (swiperEl.swiper) {
83
+ swiperEl.swiper.update();
84
+ }
85
+ }
86
+ for (const tabsEl of c.querySelectorAll('.tabs')) {
87
+ setInitLineStyles(tabsEl);
88
+ }
89
+ // Инициализируем полученный HTML
90
+ initTabsContent($content[index]);
91
+ } else {
92
+ c.hidden = true;
93
+ }
94
+ }
95
+ } catch (error) {
96
+ hideLoader();
97
+ if (error.status === 401) {
98
+ location.reload();
99
+ } else {
100
+ errorHandler(error);
101
+ }
102
+ }
103
+ } else {
104
+ // Переключаем таб
105
+ for (const i of $item) i.disabled = false;
106
+ $el.disabled = true;
107
+ for (const [i, c] of $content.entries()) {
108
+ if (i === index) {
109
+ c.hidden = false;
110
+ for (const swiperEl of c.querySelectorAll('.swiper')) {
111
+ if (swiperEl.swiper) {
112
+ swiperEl.swiper.update();
113
+ }
114
+ }
115
+ for (const tabsEl of c.querySelectorAll('.tabs')) {
116
+ setInitLineStyles(tabsEl);
117
+ }
118
+ // Инициализируем полученный HTML
119
+ initTabsContent($content[index]);
120
+ } else {
121
+ c.hidden = true;
122
+ }
123
+ }
124
+ }
125
+
126
+ if ($nav.swiper) {
127
+ $nav.swiper.slideTo(index);
128
+ }
129
+
130
+ if ($line) {
131
+ setLeftWidth($line, $el);
132
+ }
133
+ }
134
+ };
135
+
136
+ if ($nav.swiper) {
137
+ $nav.swiper.destroy();
138
+ for (const i of $item) i.removeEventListener('click', handleItemClick);
139
+ }
140
+
141
+ const { default: Swiper } = await import('swiper');
142
+
143
+ $nav.classList.add('swiper');
144
+ $list.classList.add('swiper-wrapper');
145
+ for (const i of $item) i.classList.add('swiper-slide');
146
+
147
+ new Swiper($nav, {
148
+ speed: cssVar('--duration-effect-s'),
149
+ slidesPerView: 'auto',
150
+ freeMode: true,
151
+ on: {
152
+ init() {
153
+ if (!this.isBeginning) {
154
+ $nav.classList.toggle('tabs__nav_shadow-start', true);
155
+ }
156
+ if (!this.isEnd) {
157
+ $nav.classList.toggle('tabs__nav_shadow-end', true);
158
+ }
159
+ },
160
+ sliderMove() {
161
+ $nav.classList.toggle('tabs__nav_shadow-start', !this.isBeginning);
162
+ $nav.classList.toggle('tabs__nav_shadow-end', !this.isEnd);
163
+ },
164
+ transitionStart() {
165
+ $nav.classList.toggle('tabs__nav_shadow-start', !this.isBeginning);
166
+ $nav.classList.toggle('tabs__nav_shadow-end', !this.isEnd);
167
+ },
168
+ },
169
+ });
170
+
171
+ // Устанавливаем стили для линии при загрузке страницы
172
+ if ($line) {
173
+ setTimeout(() => {
174
+ setInitLineStyles($b);
175
+ });
176
+ }
177
+
178
+ for (const i of $item) i.addEventListener('click', handleItemClick);
179
+ };
180
+
181
+ document.body.addEventListener('click', async (e) => {
182
+ if (e.target.closest('[data-tab-name]')) {
183
+ e.preventDefault();
184
+ const name = e.target.dataset.tabName;
185
+ const $tabItem = document.querySelector(`.tabs__item[data-name="${name}"]`);
186
+ const $tabs = $tabItem.closest('.tabs');
187
+ if (!isInViewport($tabs)) {
188
+ await scrollTo($tabs, 15);
189
+ }
190
+ $tabItem.click();
191
+ }
192
+ });
@@ -0,0 +1,137 @@
1
+ @use '../../variables' as *;
2
+
3
+ $b: '.tabs';
4
+
5
+ #{$b} {
6
+ &_white-bg {
7
+ }
8
+
9
+ &__nav {
10
+ margin-top: -10px; // Не -12, потому что у вкладки может быть элемент sup
11
+ overflow: hidden;
12
+ position: relative;
13
+ width: 100%;
14
+
15
+ @media (--tablet-portrait-down) {
16
+ margin-left: -4px * 4;
17
+ margin-right: -4px * 4;
18
+ padding-left: 4px * 4;
19
+ padding-right: 4px * 4;
20
+ width: calc(100% + 32px);
21
+ }
22
+
23
+ .account & {
24
+ @media (--tablet-portrait-down) {
25
+ margin-left: -4px * 6;
26
+ margin-right: -4px * 6;
27
+ padding-left: 4px * 6;
28
+ padding-right: 4px * 6;
29
+ }
30
+ }
31
+
32
+ &_shadow-start {
33
+ &::before {
34
+ @media (--tablet-landscape-up) {
35
+ background-image: linear-gradient(-90deg, rgba($content-bg-grey, 0%), $content-bg-grey);
36
+ content: '';
37
+ height: calc(100% - #{$tabs-border-width});
38
+ left: 0;
39
+ position: absolute;
40
+ top: 0;
41
+ width: 4px * 4;
42
+ z-index: 2;
43
+ }
44
+
45
+ #{$b}_white-bg & {
46
+ @media (--tablet-landscape-up) {
47
+ background-image: linear-gradient(-90deg, rgba($content-bg, 0%), $content-bg);
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ &_shadow-end {
54
+ &::after {
55
+ @media (--tablet-landscape-up) {
56
+ background-image: linear-gradient(90deg, rgba($content-bg-grey, 0%), $content-bg-grey);
57
+ content: '';
58
+ height: calc(100% - #{$tabs-border-width});
59
+ position: absolute;
60
+ right: 0;
61
+ top: 0;
62
+ width: 4px * 4;
63
+ z-index: 2;
64
+ }
65
+
66
+ #{$b}_white-bg & {
67
+ @media (--tablet-landscape-up) {
68
+ background-image: linear-gradient(90deg, rgba($content-bg, 0%), $content-bg);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ &__list {
76
+ border-bottom: $tabs-border-width solid $tabs-border-color;
77
+ display: flex;
78
+ position: relative;
79
+ }
80
+
81
+ &__item {
82
+ border-bottom: $tabs-border-width solid $tabs-border-color;
83
+ display: block;
84
+ margin-bottom: $tabs-border-width * -1;
85
+ padding: 0 4px * 4;
86
+ padding-bottom: 4px * 3;
87
+ padding-top: 4px * 3;
88
+
89
+ &:first-of-type {
90
+ padding-left: 0;
91
+ }
92
+
93
+ &:last-of-type {
94
+ padding-right: 0;
95
+ }
96
+
97
+ div#{$b}__item + &:any-link,
98
+ div#{$b}__item + &:enabled {
99
+ padding-left: 4px * 4;
100
+ }
101
+
102
+ &.swiper-slide {
103
+ width: auto;
104
+ }
105
+ }
106
+
107
+ &__label {
108
+ white-space: nowrap;
109
+
110
+ @include font($tabs-label-font);
111
+ }
112
+
113
+ &__counter {
114
+ background-color: $tabs-counter-bg;
115
+ border-radius: $tabs-counter-radius;
116
+ color: $tabs-counter-color;
117
+ height: 4px * 5;
118
+ padding-bottom: 2px;
119
+ padding-left: 4px * 2;
120
+ padding-right: 4px * 2;
121
+ padding-top: 3px;
122
+
123
+ @include font($tabs-counter-font);
124
+ }
125
+
126
+ &__line {
127
+ background-color: $tabs-line-color;
128
+ bottom: $tabs-border-width * -1;
129
+ display: block;
130
+ height: $tabs-border-width;
131
+ left: 0;
132
+ position: absolute;
133
+ }
134
+
135
+ &__content {
136
+ }
137
+ }
@@ -0,0 +1,27 @@
1
+ @use '../../variables' as *;
2
+
3
+ .time-select {
4
+ align-items: center;
5
+ display: flex;
6
+
7
+ &::before {
8
+ background-color: $time-select-dash-color;
9
+ content: '';
10
+ height: 1px;
11
+ margin: 0 4px * 3;
12
+ order: 2;
13
+ width: 4px * 4;
14
+ }
15
+
16
+ &__item {
17
+ width: 4px * 28;
18
+
19
+ &:first-child {
20
+ order: 1;
21
+ }
22
+
23
+ &:last-child {
24
+ order: 3;
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,76 @@
1
+ @use '../../variables' as *;
2
+
3
+ $b: '.toggle';
4
+
5
+ #{$b} {
6
+ align-items: center;
7
+ display: flex;
8
+
9
+ &__input {
10
+ background-color: $toggle-bg;
11
+ border: $toggle-border-width solid $toggle-border-color;
12
+ border-radius: $toggle-radius;
13
+ cursor: pointer;
14
+ flex-shrink: 0;
15
+ height: 4px * 6;
16
+ position: relative;
17
+ transition-duration: var(--duration-micro-m);
18
+ transition-property: background-color, border-color;
19
+ transition-timing-function: var(--easing-standard);
20
+ width: 4px * 12;
21
+
22
+ #{$b}__label + & {
23
+ margin-left: 4px * 3;
24
+ }
25
+
26
+ :disabled ~ & {
27
+ background-color: $toggle-disabled-bg;
28
+ border-color: $toggle-disabled-border-color;
29
+ cursor: default;
30
+ }
31
+
32
+ :checked ~ & {
33
+ background-color: $toggle-active-bg;
34
+ border-color: $toggle-active-border-color;
35
+ }
36
+
37
+ :checked:disabled ~ & {
38
+ background-color: $toggle-active-disabled-bg;
39
+ border-color: $toggle-active-disabled-border-color;
40
+ }
41
+
42
+ &::before {
43
+ background-color: $toggle-check-color;
44
+ border-radius: $toggle-check-radius;
45
+ content: '';
46
+ height: 4px * 5;
47
+ left: 1px;
48
+ position: absolute;
49
+ top: 1px;
50
+ transition-duration: var(--duration-micro-m);
51
+ transition-property: background-color, transform;
52
+ transition-timing-function: var(--easing-standard);
53
+ width: 4px * 5;
54
+
55
+ :disabled ~ & {
56
+ background-color: $toggle-disabled-check-color;
57
+ }
58
+
59
+ :checked ~ & {
60
+ background-color: $toggle-active-check-color;
61
+ transform: translateX(24px);
62
+ }
63
+
64
+ :checked:disabled ~ & {
65
+ background-color: $toggle-active-disabled-check-color;
66
+ }
67
+ }
68
+ }
69
+
70
+ &__label {
71
+ color: $toggle-label-color;
72
+ margin-left: 4px * 3;
73
+
74
+ @include font($toggle-label-font);
75
+ }
76
+ }
@@ -0,0 +1,69 @@
1
+ /* globals BX */
2
+
3
+ import { cssVar } from '../../helpers/css-var.js';
4
+ import { errorHandler } from '../../helpers/error-handler.js';
5
+
6
+ export const init = async ($b) => {
7
+ const { createTooltip } = await import('@advdominion/tooltip');
8
+ const title = $b.dataset.tooltipTitle;
9
+ const content = title ? `<div class="tooltip__title">${title}</div>${$b.dataset.tooltip}` : $b.dataset.tooltip;
10
+
11
+ return new Promise((resolve) => {
12
+ if ($b._tooltip) {
13
+ $b._tooltip.setContent(content);
14
+ return resolve();
15
+ }
16
+
17
+ const tooltipFetch = $b.dataset.tooltipFetch;
18
+
19
+ let appendTo = document.body;
20
+ const $special = $b.closest('.dialog, .sidebar, .filter, .compare-pane');
21
+ if ($special) {
22
+ appendTo = $special;
23
+ }
24
+
25
+ createTooltip($b, content, {
26
+ appendTo,
27
+ delay: [cssVar('--duration-micro-s'), cssVar('--duration-micro-s')],
28
+ duration: [cssVar('--duration-enter-s'), cssVar('--duration-leave-s')],
29
+ easing: [cssVar('--easing-deceleration'), cssVar('--easing-acceleration')],
30
+ theme: 'small-light',
31
+ onCreate(instance) {
32
+ if (tooltipFetch) {
33
+ instance._isFetching = false;
34
+ instance._isFetched = false;
35
+ }
36
+ resolve();
37
+ },
38
+ async onShow(instance) {
39
+ if (tooltipFetch && !instance._isFetching && !instance._isFetched) {
40
+ instance.setContent('Загрузка...');
41
+ instance._isFetching = true;
42
+ try {
43
+ const response = await fetch(tooltipFetch, {
44
+ method: 'GET',
45
+ headers: {
46
+ 'X-Requested-With': 'XMLHttpRequest',
47
+ 'X-Session-Id': BX.message('bitrix_sessid'),
48
+ },
49
+ });
50
+ if (!response.ok) {
51
+ throw response;
52
+ }
53
+ const data = await response.text();
54
+ instance._isFetching = false;
55
+ instance._isFetched = true;
56
+ instance.setContent(data);
57
+ } catch (error) {
58
+ if (error.status === 401) {
59
+ location.reload();
60
+ } else {
61
+ instance._isFetching = false;
62
+ errorHandler(error);
63
+ }
64
+ }
65
+ }
66
+ },
67
+ });
68
+ });
69
+ };
@@ -0,0 +1,112 @@
1
+ @use '../../variables' as *;
2
+
3
+ $b: '.tooltip';
4
+
5
+ #{$b} {
6
+ left: 0;
7
+ max-width: calc(100vw - 32px);
8
+ position: absolute;
9
+ top: 0;
10
+ width: max-content;
11
+ z-index: 200;
12
+
13
+ @media (--tablet-portrait-up) {
14
+ max-width: 300px;
15
+ }
16
+
17
+ &__arrow {
18
+ #{$b}_theme_light &,
19
+ #{$b}_theme_small-light &,
20
+ #{$b}_theme_actions & {
21
+ background-color: $tooltip-light-bg;
22
+
23
+ @include dark-border;
24
+ }
25
+
26
+ #{$b}_theme_light#{$b}_side_top &,
27
+ #{$b}_theme_small-light#{$b}_side_top &,
28
+ #{$b}_theme_actions#{$b}_side_top & {
29
+ @include dark-border-disable((top, left));
30
+ }
31
+
32
+ #{$b}_theme_light#{$b}_side_bottom &,
33
+ #{$b}_theme_small-light#{$b}_side_bottom &,
34
+ #{$b}_theme_actions#{$b}_side_bottom & {
35
+ @include dark-border-disable((right, bottom));
36
+ }
37
+
38
+ #{$b}_theme_light#{$b}_side_left &,
39
+ #{$b}_theme_small-light#{$b}_side_left &,
40
+ #{$b}_theme_actions#{$b}_side_left & {
41
+ @include dark-border-disable((bottom, left));
42
+ }
43
+
44
+ #{$b}_theme_light#{$b}_side_right &,
45
+ #{$b}_theme_small-light#{$b}_side_right &,
46
+ #{$b}_theme_actions#{$b}_side_right & {
47
+ @include dark-border-disable((top, right));
48
+ }
49
+
50
+ #{$b}_theme_dark &,
51
+ #{$b}_theme_small-dark & {
52
+ background-color: $tooltip-dark-bg;
53
+ }
54
+
55
+ #{$b}_theme_light &,
56
+ #{$b}_theme_dark &,
57
+ #{$b}_theme_actions & {
58
+ height: 10px;
59
+ width: 10px;
60
+ }
61
+
62
+ #{$b}_theme_small-light &,
63
+ #{$b}_theme_small-dark & {
64
+ height: 8px;
65
+ width: 8px;
66
+ }
67
+ }
68
+
69
+ &__container {
70
+ #{$b}_theme_light &,
71
+ #{$b}_theme_small-light &,
72
+ #{$b}_theme_actions & {
73
+ background-color: $tooltip-light-bg;
74
+ border-radius: $tooltip-radius;
75
+ box-shadow: $tooltip-shadow;
76
+ color: $tooltip-light-color;
77
+
78
+ @include dark-border;
79
+ }
80
+
81
+ #{$b}_theme_dark &,
82
+ #{$b}_theme_small-dark & {
83
+ background-color: $tooltip-dark-bg;
84
+ border-radius: $tooltip-radius;
85
+ color: $tooltip-dark-color;
86
+ }
87
+
88
+ #{$b}_theme_light &,
89
+ #{$b}_theme_dark & {
90
+ padding: 16px 24px;
91
+
92
+ @include font($tooltip-font);
93
+ }
94
+
95
+ #{$b}_theme_small-light &,
96
+ #{$b}_theme_small-dark & {
97
+ padding: 12px 16px;
98
+
99
+ @include font($tooltip-small-font);
100
+ }
101
+
102
+ #{$b}_theme_actions & {
103
+ @include font($tooltip-font);
104
+ }
105
+ }
106
+
107
+ &__title {
108
+ margin-bottom: 4px * 2;
109
+
110
+ @include font($tooltip-title-font);
111
+ }
112
+ }