funda-ui 4.7.515 → 4.7.525
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.
- package/CascadingSelect/index.css +105 -88
- package/CascadingSelect/index.js +23 -23
- package/CascadingSelectE2E/index.css +105 -88
- package/CascadingSelectE2E/index.js +24 -24
- package/Select/index.js +110 -88
- package/Tooltip/index.css +69 -68
- package/Tooltip/index.d.ts +15 -1
- package/Tooltip/index.js +153 -57
- package/lib/cjs/CascadingSelect/index.js +23 -23
- package/lib/cjs/CascadingSelectE2E/index.js +24 -24
- package/lib/cjs/Select/index.js +110 -88
- package/lib/cjs/Tooltip/index.d.ts +15 -1
- package/lib/cjs/Tooltip/index.js +153 -57
- package/lib/css/CascadingSelect/index.css +105 -88
- package/lib/css/CascadingSelectE2E/index.css +105 -88
- package/lib/css/Tooltip/index.css +69 -68
- package/lib/esm/CascadingSelect/Group.tsx +3 -5
- package/lib/esm/CascadingSelect/index.scss +89 -68
- package/lib/esm/CascadingSelect/index.tsx +21 -20
- package/lib/esm/CascadingSelectE2E/Group.tsx +4 -3
- package/lib/esm/CascadingSelectE2E/index.scss +83 -63
- package/lib/esm/CascadingSelectE2E/index.tsx +22 -21
- package/lib/esm/Select/index.tsx +165 -148
- package/lib/esm/Tooltip/index.scss +63 -60
- package/lib/esm/Tooltip/index.tsx +143 -44
- package/package.json +1 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
1
3
|
/* ======================================================
|
|
2
4
|
<!-- Tooltip -->
|
|
3
5
|
/* ====================================================== */
|
|
@@ -16,22 +18,22 @@
|
|
|
16
18
|
* 10. Size
|
|
17
19
|
*/
|
|
18
20
|
|
|
19
|
-
.tooltip__wrapper {
|
|
20
|
-
|
|
21
|
-
--tooltip-box-shadow: 0 5px 15px 0 rgba(0,0,0,.07), 0 15px 35px 0 rgba(50,50,93,.1);
|
|
22
|
-
--tooltip-content-bg: rgba(17, 17, 17, 0.9);
|
|
23
|
-
--tooltip-content-color: #fff;
|
|
24
|
-
--tooltip-content-font-size: 0.75em;
|
|
25
|
-
--tooltip-content-padding-x: 1em;
|
|
26
|
-
--tooltip-content-padding-y: .5em;
|
|
27
|
-
--tooltip-content-line-height: 1.5;
|
|
28
|
-
--tooltip-arrow-bg-top: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
29
|
-
--tooltip-arrow-bg-bottom: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
30
|
-
--tooltip-arrow-bg-left: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
31
|
-
--tooltip-arrow-bg-right: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
32
|
-
|
|
33
|
-
--tooltip-arrow-width: 18px;
|
|
34
|
-
--tooltip-arrow-height: 6px;
|
|
21
|
+
.cus-tooltip__wrapper {
|
|
22
|
+
|
|
23
|
+
--cus-tooltip-box-shadow: 0 5px 15px 0 rgba(0,0,0,.07), 0 15px 35px 0 rgba(50,50,93,.1);
|
|
24
|
+
--cus-tooltip-content-bg: rgba(17, 17, 17, 0.9);
|
|
25
|
+
--cus-tooltip-content-color: #fff;
|
|
26
|
+
--cus-tooltip-content-font-size: 0.75em;
|
|
27
|
+
--cus-tooltip-content-padding-x: 1em;
|
|
28
|
+
--cus-tooltip-content-padding-y: .5em;
|
|
29
|
+
--cus-tooltip-content-line-height: 1.5;
|
|
30
|
+
--cus-tooltip-arrow-bg-top: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
31
|
+
--cus-tooltip-arrow-bg-bottom: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
32
|
+
--cus-tooltip-arrow-bg-left: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
33
|
+
--cus-tooltip-arrow-bg-right: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
|
|
34
|
+
|
|
35
|
+
--cus-tooltip-arrow-width: 18px;
|
|
36
|
+
--cus-tooltip-arrow-height: 6px;
|
|
35
37
|
|
|
36
38
|
|
|
37
39
|
position: absolute;
|
|
@@ -50,7 +52,7 @@
|
|
|
50
52
|
display: block !important;
|
|
51
53
|
|
|
52
54
|
&::before,
|
|
53
|
-
> .tooltip__content {
|
|
55
|
+
> .cus-tooltip__content {
|
|
54
56
|
opacity: 1;
|
|
55
57
|
}
|
|
56
58
|
}
|
|
@@ -58,21 +60,21 @@
|
|
|
58
60
|
&:focus {
|
|
59
61
|
|
|
60
62
|
&::before,
|
|
61
|
-
> .tooltip__content {
|
|
63
|
+
> .cus-tooltip__content {
|
|
62
64
|
opacity: 1;
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
|
|
67
69
|
&::before,
|
|
68
|
-
> .tooltip__content {
|
|
70
|
+
> .cus-tooltip__content {
|
|
69
71
|
backface-visibility: hidden;
|
|
70
72
|
will-change: transform;
|
|
71
73
|
opacity: 0;
|
|
72
74
|
box-sizing: border-box;
|
|
73
75
|
z-index: 10;
|
|
74
76
|
transform-origin: top;
|
|
75
|
-
box-shadow: var(--tooltip-box-shadow);
|
|
77
|
+
box-shadow: var(--cus-tooltip-box-shadow);
|
|
76
78
|
transition: none !important; /* Don't use transition if position is outside window */
|
|
77
79
|
}
|
|
78
80
|
|
|
@@ -84,18 +86,19 @@
|
|
|
84
86
|
---------------------------
|
|
85
87
|
*/
|
|
86
88
|
|
|
87
|
-
> .tooltip__content {
|
|
88
|
-
|
|
89
|
+
> .cus-tooltip__content {
|
|
90
|
+
pointer-events: auto;
|
|
91
|
+
background: var(--cus-tooltip-content-bg);
|
|
89
92
|
border-radius: 4px;
|
|
90
|
-
color: var(--tooltip-content-color);
|
|
93
|
+
color: var(--cus-tooltip-content-color);
|
|
91
94
|
content: attr(aria-label);
|
|
92
|
-
font-size: var(--tooltip-content-font-size);
|
|
95
|
+
font-size: var(--cus-tooltip-content-font-size);
|
|
93
96
|
font-weight: normal;
|
|
94
97
|
text-transform: none;
|
|
95
|
-
padding: var(--tooltip-content-padding-y) var(--tooltip-content-padding-x);
|
|
98
|
+
padding: var(--cus-tooltip-content-padding-y) var(--cus-tooltip-content-padding-x);
|
|
96
99
|
white-space: nowrap;
|
|
97
100
|
box-sizing: content-box;
|
|
98
|
-
line-height: var(--tooltip-content-line-height);
|
|
101
|
+
line-height: var(--cus-tooltip-content-line-height);
|
|
99
102
|
|
|
100
103
|
|
|
101
104
|
img {
|
|
@@ -115,22 +118,22 @@
|
|
|
115
118
|
|
|
116
119
|
&[data-microtip-position|="top"] {
|
|
117
120
|
&::before {
|
|
118
|
-
background: var(--tooltip-arrow-bg-top);
|
|
119
|
-
height: var(--tooltip-arrow-height);
|
|
120
|
-
width: var(--tooltip-arrow-width);
|
|
121
|
+
background: var(--cus-tooltip-arrow-bg-top);
|
|
122
|
+
height: var(--cus-tooltip-arrow-height);
|
|
123
|
+
width: var(--cus-tooltip-arrow-width);
|
|
121
124
|
}
|
|
122
125
|
|
|
123
|
-
> .tooltip__content {
|
|
124
|
-
margin-bottom: var(--tooltip-arrow-height);
|
|
126
|
+
> .cus-tooltip__content {
|
|
127
|
+
margin-bottom: var(--cus-tooltip-arrow-height);
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
&::before {
|
|
128
|
-
top: calc(100% - var(--tooltip-arrow-height));
|
|
129
|
-
left: calc(var(--tooltip-arrow-width)/2 * -1);
|
|
131
|
+
top: calc(100% - var(--cus-tooltip-arrow-height));
|
|
132
|
+
left: calc(var(--cus-tooltip-arrow-width)/2 * -1);
|
|
130
133
|
}
|
|
131
134
|
|
|
132
|
-
> .tooltip__content {
|
|
133
|
-
bottom: calc(100% + var(--tooltip-arrow-height));
|
|
135
|
+
> .cus-tooltip__content {
|
|
136
|
+
bottom: calc(100% + var(--cus-tooltip-arrow-height));
|
|
134
137
|
left: 50%;
|
|
135
138
|
transform: translateX(-50%);
|
|
136
139
|
}
|
|
@@ -144,10 +147,10 @@
|
|
|
144
147
|
*/
|
|
145
148
|
|
|
146
149
|
&[data-microtip-position="top-left"] {
|
|
147
|
-
> .tooltip__content {
|
|
148
|
-
bottom: calc(100% + var(--tooltip-arrow-height));
|
|
150
|
+
> .cus-tooltip__content {
|
|
151
|
+
bottom: calc(100% + var(--cus-tooltip-arrow-height));
|
|
149
152
|
left: 50%;
|
|
150
|
-
transform: translateX(calc(-100% + var(--tooltip-arrow-width)));
|
|
153
|
+
transform: translateX(calc(-100% + var(--cus-tooltip-arrow-width)));
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
}
|
|
@@ -161,10 +164,10 @@
|
|
|
161
164
|
*/
|
|
162
165
|
|
|
163
166
|
&[data-microtip-position="top-right"] {
|
|
164
|
-
> .tooltip__content {
|
|
165
|
-
bottom: calc(100% + var(--tooltip-arrow-height));
|
|
167
|
+
> .cus-tooltip__content {
|
|
168
|
+
bottom: calc(100% + var(--cus-tooltip-arrow-height));
|
|
166
169
|
left: 50%;
|
|
167
|
-
transform: translateX(calc(0% - var(--tooltip-arrow-width)));
|
|
170
|
+
transform: translateX(calc(0% - var(--cus-tooltip-arrow-width)));
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
|
|
@@ -177,25 +180,25 @@
|
|
|
177
180
|
|
|
178
181
|
&[data-microtip-position|="bottom"] {
|
|
179
182
|
&::before {
|
|
180
|
-
background: var(--tooltip-arrow-bg-bottom);
|
|
181
|
-
height: var(--tooltip-arrow-height);
|
|
182
|
-
width: var(--tooltip-arrow-width);
|
|
183
|
+
background: var(--cus-tooltip-arrow-bg-bottom);
|
|
184
|
+
height: var(--cus-tooltip-arrow-height);
|
|
185
|
+
width: var(--cus-tooltip-arrow-width);
|
|
183
186
|
margin-top: 5px;
|
|
184
187
|
margin-bottom: 0;
|
|
185
188
|
}
|
|
186
189
|
|
|
187
|
-
> .tooltip__content {
|
|
188
|
-
margin-top: var(--tooltip-arrow-height);
|
|
190
|
+
> .cus-tooltip__content {
|
|
191
|
+
margin-top: var(--cus-tooltip-arrow-height);
|
|
189
192
|
}
|
|
190
193
|
|
|
191
194
|
&::before {
|
|
192
|
-
bottom: calc(100% - var(--tooltip-arrow-height));
|
|
193
|
-
left: calc(var(--tooltip-arrow-width)/2 * -1);
|
|
195
|
+
bottom: calc(100% - var(--cus-tooltip-arrow-height));
|
|
196
|
+
left: calc(var(--cus-tooltip-arrow-width)/2 * -1);
|
|
194
197
|
}
|
|
195
198
|
|
|
196
|
-
> .tooltip__content {
|
|
199
|
+
> .cus-tooltip__content {
|
|
197
200
|
bottom: auto;
|
|
198
|
-
top: calc(100% + var(--tooltip-arrow-height));
|
|
201
|
+
top: calc(100% + var(--cus-tooltip-arrow-height));
|
|
199
202
|
left: 50%;
|
|
200
203
|
transform: translateX(-50%);
|
|
201
204
|
}
|
|
@@ -210,11 +213,11 @@
|
|
|
210
213
|
|
|
211
214
|
|
|
212
215
|
&[data-microtip-position="bottom-left"] {
|
|
213
|
-
> .tooltip__content {
|
|
216
|
+
> .cus-tooltip__content {
|
|
214
217
|
bottom: auto;
|
|
215
|
-
top: calc(100% + var(--tooltip-arrow-height));
|
|
218
|
+
top: calc(100% + var(--cus-tooltip-arrow-height));
|
|
216
219
|
left: 50%;
|
|
217
|
-
transform: translateX(calc(-100% + var(--tooltip-arrow-width)));
|
|
220
|
+
transform: translateX(calc(-100% + var(--cus-tooltip-arrow-width)));
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
|
|
@@ -226,11 +229,11 @@
|
|
|
226
229
|
|
|
227
230
|
|
|
228
231
|
&[data-microtip-position="bottom-right"] {
|
|
229
|
-
> .tooltip__content {
|
|
232
|
+
> .cus-tooltip__content {
|
|
230
233
|
bottom: auto;
|
|
231
|
-
top: calc(100% + var(--tooltip-arrow-height));
|
|
234
|
+
top: calc(100% + var(--cus-tooltip-arrow-height));
|
|
232
235
|
left: 50%;
|
|
233
|
-
transform: translateX(calc(0% - var(--tooltip-arrow-width)));
|
|
236
|
+
transform: translateX(calc(0% - var(--cus-tooltip-arrow-width)));
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
239
|
|
|
@@ -242,7 +245,7 @@
|
|
|
242
245
|
10. Size
|
|
243
246
|
---------------------------
|
|
244
247
|
*/
|
|
245
|
-
&[data-microtip-size="auto"].tooltip__content {
|
|
248
|
+
&[data-microtip-size="auto"].cus-tooltip__content {
|
|
246
249
|
white-space: nowrap;
|
|
247
250
|
width: auto;
|
|
248
251
|
max-width: 530px;
|
|
@@ -250,17 +253,17 @@
|
|
|
250
253
|
text-overflow: ellipsis;
|
|
251
254
|
}
|
|
252
255
|
|
|
253
|
-
&[data-microtip-size="small"].tooltip__content {
|
|
256
|
+
&[data-microtip-size="small"].cus-tooltip__content {
|
|
254
257
|
white-space: initial;
|
|
255
258
|
width: 80px;
|
|
256
259
|
}
|
|
257
260
|
|
|
258
|
-
&[data-microtip-size="medium"].tooltip__content {
|
|
261
|
+
&[data-microtip-size="medium"].cus-tooltip__content {
|
|
259
262
|
white-space: initial;
|
|
260
263
|
width: 150px;
|
|
261
264
|
}
|
|
262
265
|
|
|
263
|
-
&[data-microtip-size="large"].tooltip__content {
|
|
266
|
+
&[data-microtip-size="large"].cus-tooltip__content {
|
|
264
267
|
white-space: initial;
|
|
265
268
|
width: 260px;
|
|
266
269
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect } from 'react';
|
|
1
|
+
import React, { useState, useRef, useEffect, useImperativeHandle, forwardRef, useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import RootPortal from 'funda-root-portal';
|
|
4
4
|
|
|
@@ -12,7 +12,6 @@ import { getElCSS } from 'funda-utils/dist/cjs/inputsCalculation';
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
export type TooltipProps = {
|
|
17
16
|
triggerClassName?: string;
|
|
18
17
|
wrapperClassName?: string;
|
|
@@ -30,40 +29,27 @@ export type TooltipProps = {
|
|
|
30
29
|
mouseOutDelay?: number;
|
|
31
30
|
/** Set a piece of text or HTML code */
|
|
32
31
|
content?: React.ReactNode;
|
|
32
|
+
/** If true, Tooltip is controlled by parent via ref, not by mouse events */
|
|
33
|
+
controlled?: boolean;
|
|
34
|
+
/** Custom color for the popup arrow */
|
|
35
|
+
popupArrowColor?: number[];
|
|
36
|
+
/** Custom style for the popup content */
|
|
37
|
+
popupContentStyle?: React.CSSProperties;
|
|
38
|
+
/** If true, tooltip closes only if mouse does not enter wrapper within timeout after leaving trigger */
|
|
39
|
+
delayedClose?: boolean;
|
|
40
|
+
/** Timeout in ms for delayed close (ms) */
|
|
41
|
+
delayedCloseTimeout?: number;
|
|
42
|
+
/** Called when mouse enters the tooltip wrapper */
|
|
43
|
+
onContentMouseEnter?: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
44
|
+
/** Called when mouse leaves the tooltip wrapper */
|
|
45
|
+
onContentMouseLeave?: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
33
46
|
/** -- */
|
|
34
47
|
id?: string;
|
|
35
48
|
children: React.ReactNode;
|
|
36
49
|
};
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
const getDimensions = () => ({
|
|
43
|
-
width: myRef.current.offsetWidth,
|
|
44
|
-
height: myRef.current.offsetHeight
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
const handleResize = () => {
|
|
48
|
-
setDimensions(getDimensions())
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (myRef.current) {
|
|
52
|
-
setDimensions(getDimensions())
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
window.addEventListener("resize", handleResize)
|
|
56
|
-
|
|
57
|
-
return () => {
|
|
58
|
-
window.removeEventListener("resize", handleResize)
|
|
59
|
-
}
|
|
60
|
-
}, [myRef])
|
|
61
|
-
|
|
62
|
-
return dimensions;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const Tooltip = (props: TooltipProps) => {
|
|
51
|
+
// Use forwardRef to expose imperative methods
|
|
52
|
+
const Tooltip = forwardRef<any, TooltipProps>((props, ref) => {
|
|
67
53
|
const {
|
|
68
54
|
triggerClassName,
|
|
69
55
|
wrapperClassName,
|
|
@@ -75,7 +61,14 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
75
61
|
mouseOutDelay,
|
|
76
62
|
content,
|
|
77
63
|
id,
|
|
78
|
-
children
|
|
64
|
+
children,
|
|
65
|
+
controlled,
|
|
66
|
+
popupArrowColor,
|
|
67
|
+
popupContentStyle,
|
|
68
|
+
delayedClose,
|
|
69
|
+
delayedCloseTimeout,
|
|
70
|
+
onContentMouseEnter,
|
|
71
|
+
onContentMouseLeave
|
|
79
72
|
} = props;
|
|
80
73
|
|
|
81
74
|
|
|
@@ -95,12 +88,62 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
95
88
|
y: 0
|
|
96
89
|
});
|
|
97
90
|
|
|
91
|
+
const popupArrowStyle = useMemo(() => {
|
|
92
|
+
if (
|
|
93
|
+
typeof popupArrowColor !== 'undefined' &&
|
|
94
|
+
Array.isArray(popupArrowColor) &&
|
|
95
|
+
popupArrowColor.length === 4
|
|
96
|
+
) {
|
|
97
|
+
return {
|
|
98
|
+
'--cus-tooltip-arrow-bg-top': `url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%28${popupArrowColor[0]},%20${popupArrowColor[1]},%20${popupArrowColor[2]},%20${popupArrowColor[3]}%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat`,
|
|
99
|
+
'--cus-tooltip-arrow-bg-bottom': `url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%28${popupArrowColor[0]},%20${popupArrowColor[1]},%20${popupArrowColor[2]},%20${popupArrowColor[3]}%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat`,
|
|
100
|
+
'--cus-tooltip-arrow-bg-left': `url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%28${popupArrowColor[0]},%20${popupArrowColor[1]},%20${popupArrowColor[2]},%20${popupArrowColor[3]}%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat`,
|
|
101
|
+
'--cus-tooltip-arrow-bg-right': `url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%28${popupArrowColor[0]},%20${popupArrowColor[1]},%20${popupArrowColor[2]},%20${popupArrowColor[3]}%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return undefined;
|
|
105
|
+
}, [popupArrowColor]);
|
|
106
|
+
|
|
107
|
+
// Expose show/hide methods to parent via ref
|
|
108
|
+
useImperativeHandle(ref, () => ({
|
|
109
|
+
show: () => {
|
|
110
|
+
// Find the trigger element
|
|
111
|
+
const triggerEl = rootRef.current;
|
|
112
|
+
if (triggerEl) {
|
|
113
|
+
// Calculate position (copy from handleMouseEnter)
|
|
114
|
+
const { x, y, width, height } = getAbsolutePositionOfStage(triggerEl);
|
|
115
|
+
let pos = triggerEl.dataset.microtipPosition;
|
|
116
|
+
if (typeof pos === 'undefined') pos = 'top';
|
|
117
|
+
|
|
118
|
+
if (pos.indexOf('top') >= 0) {
|
|
119
|
+
setPosition({
|
|
120
|
+
x: x + (width / 2) + 'px',
|
|
121
|
+
y: y - height - POS_OFFSET + 'px'
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (pos.indexOf('bottom') >= 0) {
|
|
125
|
+
setPosition({
|
|
126
|
+
x: x + (width / 2) + 'px',
|
|
127
|
+
y: y + height + POS_OFFSET + 'px'
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
setIsShow(true);
|
|
132
|
+
},
|
|
133
|
+
hide: () => {
|
|
134
|
+
hideTip();
|
|
135
|
+
}
|
|
136
|
+
}), [POS_OFFSET]);
|
|
98
137
|
|
|
99
138
|
|
|
100
139
|
// click outside
|
|
101
140
|
useClickOutside({
|
|
102
|
-
enabled: isShow && rootRef.current,
|
|
141
|
+
enabled: isShow && rootRef.current && !controlled, // Only auto-close if not controlled
|
|
103
142
|
isOutside: (event: any) => {
|
|
143
|
+
// Prevent closing when clicking inside the tooltip wrapper
|
|
144
|
+
if (modalRef.current && modalRef.current.contains(event.target)) {
|
|
145
|
+
return false; // Click is inside the tooltip wrapper, do not close
|
|
146
|
+
}
|
|
104
147
|
// close dropdown when other dropdown is opened
|
|
105
148
|
return (
|
|
106
149
|
(rootRef.current !== event.target && !rootRef.current.contains(event.target as HTMLElement))
|
|
@@ -109,7 +152,7 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
109
152
|
handle: (event: any) => {
|
|
110
153
|
hideTip();
|
|
111
154
|
}
|
|
112
|
-
}, [isShow, rootRef]);
|
|
155
|
+
}, [isShow, rootRef, controlled]);
|
|
113
156
|
|
|
114
157
|
|
|
115
158
|
|
|
@@ -153,7 +196,7 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
153
196
|
const _modalRef: any = modalRef.current;
|
|
154
197
|
if (_modalRef === null) return;
|
|
155
198
|
|
|
156
|
-
const _modalContent = _modalRef.querySelector('.tooltip__content');
|
|
199
|
+
const _modalContent = _modalRef.querySelector('.cus-tooltip__content');
|
|
157
200
|
const _modalBox = _modalContent.getBoundingClientRect();
|
|
158
201
|
if (typeof _modalContent.dataset.offset === 'undefined' && _modalBox.left > 0) {
|
|
159
202
|
|
|
@@ -197,6 +240,7 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
197
240
|
};
|
|
198
241
|
|
|
199
242
|
function handleMouseEnter(e: any) {
|
|
243
|
+
if (controlled) return; // Do nothing if controlled
|
|
200
244
|
stopTimerHover();
|
|
201
245
|
stopTimerMouseout();
|
|
202
246
|
startTimerHover();
|
|
@@ -239,6 +283,7 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
239
283
|
|
|
240
284
|
|
|
241
285
|
function handleMouseLeave() {
|
|
286
|
+
if (controlled) return; // Do nothing if controlled
|
|
242
287
|
stopTimerHover();
|
|
243
288
|
stopTimerMouseout();
|
|
244
289
|
startTimerMouseout();
|
|
@@ -250,10 +295,60 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
250
295
|
}
|
|
251
296
|
|
|
252
297
|
|
|
298
|
+
// Timer for delayed close
|
|
299
|
+
const delayedCloseTimerRef = useRef<any>(null);
|
|
300
|
+
const DELAYED_CLOSE_TIMEOUT = typeof delayedCloseTimeout === 'number' ? delayedCloseTimeout : 1500;
|
|
301
|
+
|
|
302
|
+
// Handler for mouse leave on trigger (when delayedClose is enabled)
|
|
303
|
+
function handleTriggerMouseLeave() {
|
|
304
|
+
if (controlled) return;
|
|
305
|
+
if (delayedClose) {
|
|
306
|
+
// Start delayed close timer
|
|
307
|
+
if (delayedCloseTimerRef.current) clearTimeout(delayedCloseTimerRef.current);
|
|
308
|
+
delayedCloseTimerRef.current = setTimeout(() => {
|
|
309
|
+
hideTip();
|
|
310
|
+
}, DELAYED_CLOSE_TIMEOUT);
|
|
311
|
+
} else {
|
|
312
|
+
stopTimerHover();
|
|
313
|
+
stopTimerMouseout();
|
|
314
|
+
startTimerMouseout();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Handler for mouse enter on wrapper (cancel delayed close)
|
|
319
|
+
function handleWrapperMouseEnter(event?: React.MouseEvent<HTMLDivElement>) {
|
|
320
|
+
if (controlled) return;
|
|
321
|
+
if (delayedClose && delayedCloseTimerRef.current) {
|
|
322
|
+
clearTimeout(delayedCloseTimerRef.current);
|
|
323
|
+
delayedCloseTimerRef.current = null;
|
|
324
|
+
}
|
|
325
|
+
// Call user-provided handler if present
|
|
326
|
+
if (onContentMouseEnter && event) {
|
|
327
|
+
onContentMouseEnter(event);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Handler for mouse leave on wrapper (restart delayed close timer)
|
|
332
|
+
function handleWrapperMouseLeave(event?: React.MouseEvent<HTMLDivElement>) {
|
|
333
|
+
if (controlled) return;
|
|
334
|
+
if (delayedClose) {
|
|
335
|
+
if (delayedCloseTimerRef.current) clearTimeout(delayedCloseTimerRef.current);
|
|
336
|
+
delayedCloseTimerRef.current = setTimeout(() => {
|
|
337
|
+
hideTip();
|
|
338
|
+
}, DELAYED_CLOSE_TIMEOUT);
|
|
339
|
+
}
|
|
340
|
+
// Call user-provided handler if present
|
|
341
|
+
if (onContentMouseLeave && event) {
|
|
342
|
+
onContentMouseLeave(event);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
|
|
253
347
|
useEffect(() => {
|
|
254
348
|
return () => {
|
|
255
349
|
stopTimerHover();
|
|
256
350
|
stopTimerMouseout();
|
|
351
|
+
if (delayedCloseTimerRef.current) clearTimeout(delayedCloseTimerRef.current);
|
|
257
352
|
};
|
|
258
353
|
}, []);
|
|
259
354
|
|
|
@@ -268,15 +363,15 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
268
363
|
|
|
269
364
|
<div
|
|
270
365
|
ref={rootRef}
|
|
271
|
-
data-overlay-id={`tooltip__wrapper-${idRes}`}
|
|
366
|
+
data-overlay-id={`cus-tooltip__wrapper-${idRes}`}
|
|
272
367
|
className={combinedCls(
|
|
273
|
-
'tooltip__trigger',
|
|
368
|
+
'cus-tooltip__trigger',
|
|
274
369
|
clsWrite(triggerClassName, 'd-inline-block')
|
|
275
370
|
)}
|
|
276
371
|
data-microtip-position={direction || 'top'}
|
|
277
372
|
data-microtip-size={size || 'auto'}
|
|
278
373
|
onMouseEnter={handleMouseEnter}
|
|
279
|
-
onMouseLeave={handleMouseLeave}
|
|
374
|
+
onMouseLeave={delayedClose ? handleTriggerMouseLeave : handleMouseLeave}
|
|
280
375
|
>
|
|
281
376
|
{children}
|
|
282
377
|
</div>
|
|
@@ -285,9 +380,9 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
285
380
|
<RootPortal show={isShow} containerClassName="Tooltip">
|
|
286
381
|
<div
|
|
287
382
|
ref={modalRef}
|
|
288
|
-
id={`tooltip__wrapper-${idRes}`}
|
|
383
|
+
id={`cus-tooltip__wrapper-${idRes}`}
|
|
289
384
|
className={combinedCls(
|
|
290
|
-
'tooltip__wrapper',
|
|
385
|
+
'cus-tooltip__wrapper',
|
|
291
386
|
wrapperClassName,
|
|
292
387
|
'active'
|
|
293
388
|
)}
|
|
@@ -297,10 +392,15 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
297
392
|
style={{
|
|
298
393
|
left: position.x,
|
|
299
394
|
top: position.y,
|
|
300
|
-
display: 'none'
|
|
395
|
+
display: 'none',
|
|
396
|
+
...popupArrowStyle
|
|
301
397
|
}}
|
|
398
|
+
onMouseEnter={delayedClose || onContentMouseEnter ? (e) => handleWrapperMouseEnter(e) : undefined}
|
|
399
|
+
onMouseLeave={delayedClose || onContentMouseLeave ? (e) => handleWrapperMouseLeave(e) : undefined}
|
|
302
400
|
>
|
|
303
|
-
<div className="tooltip__content"
|
|
401
|
+
<div className="cus-tooltip__content" style={{
|
|
402
|
+
...popupContentStyle
|
|
403
|
+
}}>{content}</div>
|
|
304
404
|
</div>
|
|
305
405
|
|
|
306
406
|
</RootPortal>
|
|
@@ -311,7 +411,6 @@ const Tooltip = (props: TooltipProps) => {
|
|
|
311
411
|
|
|
312
412
|
</>
|
|
313
413
|
)
|
|
314
|
-
};
|
|
315
|
-
|
|
414
|
+
});
|
|
316
415
|
|
|
317
416
|
export default Tooltip;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "UIUX Lab",
|
|
3
3
|
"email": "uiuxlab@gmail.com",
|
|
4
4
|
"name": "funda-ui",
|
|
5
|
-
"version": "4.7.
|
|
5
|
+
"version": "4.7.525",
|
|
6
6
|
"description": "React components using pure Bootstrap 5+ which does not contain any external style and script libraries.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|