dce-reactkit 3.6.28 → 3.7.1-beta.2
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/dist/cjs/index.js +179 -466
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/Tooltip.d.ts +1 -6
- package/dist/esm/index.js +180 -467
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/Tooltip.d.ts +1 -6
- package/dist/index.d.ts +1 -5
- package/package.json +2 -1
- package/src/components/AppWrapper.tsx +38 -0
- package/src/components/Tooltip.tsx +28 -498
|
@@ -3,14 +3,9 @@
|
|
|
3
3
|
* @author Gabe Abrams
|
|
4
4
|
*/
|
|
5
5
|
import React from 'react';
|
|
6
|
-
import { IconProp } from '@fortawesome/fontawesome-svg-core';
|
|
7
6
|
type Props = {
|
|
8
|
-
icon?: IconProp;
|
|
9
7
|
text: string;
|
|
10
|
-
children:
|
|
11
|
-
wide?: boolean;
|
|
12
|
-
thin?: boolean;
|
|
13
|
-
containerIsDisplayBlock?: boolean;
|
|
8
|
+
children: JSX.Element;
|
|
14
9
|
};
|
|
15
10
|
declare const Tooltip: React.FC<Props>;
|
|
16
11
|
export default Tooltip;
|
package/dist/index.d.ts
CHANGED
|
@@ -588,12 +588,8 @@ declare const DBEntryManagerPanel: React.FC<Props$4>;
|
|
|
588
588
|
*/
|
|
589
589
|
|
|
590
590
|
type Props$3 = {
|
|
591
|
-
icon?: IconProp;
|
|
592
591
|
text: string;
|
|
593
|
-
children:
|
|
594
|
-
wide?: boolean;
|
|
595
|
-
thin?: boolean;
|
|
596
|
-
containerIsDisplayBlock?: boolean;
|
|
592
|
+
children: JSX.Element;
|
|
597
593
|
};
|
|
598
594
|
declare const Tooltip: React.FC<Props$3>;
|
|
599
595
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dce-reactkit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.1-beta.2",
|
|
4
4
|
"description": "Shared components for Harvard DCE apps",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"@rollup/plugin-json": "^4.1.0",
|
|
41
41
|
"@rollup/plugin-node-resolve": "^13.2.1",
|
|
42
42
|
"@rollup/plugin-typescript": "^8.3.2",
|
|
43
|
+
"@types/bootstrap": "^5.2.8",
|
|
43
44
|
"@types/express": "^4.17.17",
|
|
44
45
|
"@types/jest": "^28.1.7",
|
|
45
46
|
"@types/node": "^20.2.5",
|
|
@@ -632,16 +632,54 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
632
632
|
body = children;
|
|
633
633
|
}
|
|
634
634
|
|
|
635
|
+
/* ------------- Tooltip ------------ */
|
|
636
|
+
|
|
637
|
+
const tooltipStyle = (
|
|
638
|
+
isDarkModeOn()
|
|
639
|
+
? `
|
|
640
|
+
.tooltip-inner {
|
|
641
|
+
background-color: white;
|
|
642
|
+
color: black;
|
|
643
|
+
border: 0.1rem solid black;
|
|
644
|
+
}
|
|
645
|
+
div[data-popper-placement="top"] .tooltip-arrow::before {
|
|
646
|
+
border-top-color: white !important;
|
|
647
|
+
transform: translate(0, -0.05rem);
|
|
648
|
+
}
|
|
649
|
+
`
|
|
650
|
+
: `
|
|
651
|
+
.tooltip-inner {
|
|
652
|
+
background-color: black;
|
|
653
|
+
color: black;
|
|
654
|
+
border: 0.1rem solid white;
|
|
655
|
+
}
|
|
656
|
+
div[data-popper-placement="top"] .tooltip-arrow::before {
|
|
657
|
+
border-top-color: black !important;
|
|
658
|
+
transform: translate(0, -0.05rem);
|
|
659
|
+
}
|
|
660
|
+
`
|
|
661
|
+
);
|
|
662
|
+
|
|
635
663
|
/*----------------------------------------*/
|
|
636
664
|
/* --------------- Main UI -------------- */
|
|
637
665
|
/*----------------------------------------*/
|
|
638
666
|
|
|
639
667
|
return (
|
|
640
668
|
<>
|
|
669
|
+
{/* Style */}
|
|
641
670
|
<style>
|
|
642
671
|
{style}
|
|
643
672
|
</style>
|
|
673
|
+
|
|
674
|
+
{/* Tooltip Style */}
|
|
675
|
+
<style>
|
|
676
|
+
{tooltipStyle}
|
|
677
|
+
</style>
|
|
678
|
+
|
|
679
|
+
{/* Modal */}
|
|
644
680
|
{modal}
|
|
681
|
+
|
|
682
|
+
{/* Body */}
|
|
645
683
|
{body}
|
|
646
684
|
</>
|
|
647
685
|
);
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// Import React
|
|
7
|
-
import React, { useEffect,
|
|
7
|
+
import React, { useEffect, useRef } from 'react';
|
|
8
8
|
|
|
9
|
-
// Import
|
|
10
|
-
import {
|
|
11
|
-
import { IconProp } from '@fortawesome/fontawesome-svg-core';
|
|
12
|
-
import { faCaretDown } from '@fortawesome/free-solid-svg-icons';
|
|
9
|
+
// Import Bootstrap
|
|
10
|
+
import { Tooltip as BSTooltip } from 'bootstrap';
|
|
13
11
|
|
|
14
12
|
/*------------------------------------------------------------------------*/
|
|
15
13
|
/* -------------------------------- Types ------------------------------- */
|
|
@@ -17,309 +15,10 @@ import { faCaretDown } from '@fortawesome/free-solid-svg-icons';
|
|
|
17
15
|
|
|
18
16
|
// Props definition
|
|
19
17
|
type Props = {
|
|
20
|
-
// Icon to show next to the text
|
|
21
|
-
icon?: IconProp,
|
|
22
18
|
// Text of the tooltip
|
|
23
19
|
text: string,
|
|
24
20
|
// Children to wrap in the tooltip
|
|
25
|
-
children:
|
|
26
|
-
// If true, tooltip is wider
|
|
27
|
-
wide?: boolean,
|
|
28
|
-
// If true, tooltip is thinner
|
|
29
|
-
thin?: boolean,
|
|
30
|
-
// If true, the tooltip container should be display: block
|
|
31
|
-
containerIsDisplayBlock?: boolean,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
/*------------------------------------------------------------------------*/
|
|
35
|
-
/* ------------------------------ Constants ----------------------------- */
|
|
36
|
-
/*------------------------------------------------------------------------*/
|
|
37
|
-
|
|
38
|
-
// Tooltip widths
|
|
39
|
-
const TOOLTIP_WIDTH_THIN_REM = 5;
|
|
40
|
-
const TOOLTIP_WIDTH_NORMAL_REM = 7;
|
|
41
|
-
const TOOLTIP_WIDTH_WIDE_REM = 10;
|
|
42
|
-
|
|
43
|
-
// Tooltip border radius
|
|
44
|
-
const TOOLTIP_BORDER_RADIUS_REM = 0.3;
|
|
45
|
-
|
|
46
|
-
/*------------------------------------------------------------------------*/
|
|
47
|
-
/* -------------------------------- Style ------------------------------- */
|
|
48
|
-
/*------------------------------------------------------------------------*/
|
|
49
|
-
|
|
50
|
-
const style = `
|
|
51
|
-
/* Container for contents and tooltip */
|
|
52
|
-
.Tooltip-outer-container {
|
|
53
|
-
position: relative;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/* Container for just tooltip */
|
|
57
|
-
.Tooltip-tooltip-container {
|
|
58
|
-
/* Position in middle but take no space */
|
|
59
|
-
/* (so layout of page is unaffected) */
|
|
60
|
-
position: absolute;
|
|
61
|
-
display: inline-block;
|
|
62
|
-
top: 0;
|
|
63
|
-
left: 50%;
|
|
64
|
-
height: 0;
|
|
65
|
-
width: 0;
|
|
66
|
-
overflow: visible;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/* Tooltip */
|
|
70
|
-
.Tooltip-tooltip {
|
|
71
|
-
/* Position above item */
|
|
72
|
-
display: inline-block;
|
|
73
|
-
position: absolute;
|
|
74
|
-
top: -2.3rem;
|
|
75
|
-
height: 1.8rem;
|
|
76
|
-
z-index: 1;
|
|
77
|
-
|
|
78
|
-
/* Use standard black font */
|
|
79
|
-
font-size: 1rem;
|
|
80
|
-
color: black;
|
|
81
|
-
|
|
82
|
-
/* Non-interactive */
|
|
83
|
-
pointer-events: none;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/* Tooltip box (the rectangle surrounding the text) */
|
|
87
|
-
.Tooltip-box,
|
|
88
|
-
.Tooltip-box-shadow,
|
|
89
|
-
.Tooltip-box-highlight {
|
|
90
|
-
/* Fill all space with rectangle */
|
|
91
|
-
position: absolute;
|
|
92
|
-
left: 0;
|
|
93
|
-
top: 0;
|
|
94
|
-
display: inline-block;
|
|
95
|
-
width: 100%;
|
|
96
|
-
height: 100%;
|
|
97
|
-
|
|
98
|
-
/* Rounded border */
|
|
99
|
-
border: 0.15rem solid black;
|
|
100
|
-
border-radius: ${TOOLTIP_BORDER_RADIUS_REM}rem;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/* Tooltip highlight (the bright background to the text) */
|
|
104
|
-
.Tooltip-box-highlight {
|
|
105
|
-
/* Bootstrap warning variant background */
|
|
106
|
-
background-color: rgb(255, 193, 7);
|
|
107
|
-
border-radius: ${TOOLTIP_BORDER_RADIUS_REM}rem;
|
|
108
|
-
|
|
109
|
-
/* Place on top */
|
|
110
|
-
z-index: -1;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/* Tooltip box (the black rectangle) */
|
|
114
|
-
.Tooltip-box {
|
|
115
|
-
/* Plain black background */
|
|
116
|
-
background-color: black;
|
|
117
|
-
|
|
118
|
-
/* Place in middle */
|
|
119
|
-
z-index: -2;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/* Tooltip box shadow (the white shadow beneath the box) */
|
|
123
|
-
.Tooltip-box-shadow {
|
|
124
|
-
/* White shadow */
|
|
125
|
-
box-shadow: 0 0 0.3rem white;
|
|
126
|
-
|
|
127
|
-
/* Place beneath */
|
|
128
|
-
z-index: -3;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/* Tooltip contents (the text and icon) */
|
|
132
|
-
.Tooltip-contents {
|
|
133
|
-
/* Center text, don't allow overflow */
|
|
134
|
-
white-space: nowrap;
|
|
135
|
-
overflow: hidden;
|
|
136
|
-
text-align: center;
|
|
137
|
-
text-overflow: ellipsis;
|
|
138
|
-
display: flex;
|
|
139
|
-
align-items: center;
|
|
140
|
-
justify-content: center;
|
|
141
|
-
|
|
142
|
-
/* Space within parent */
|
|
143
|
-
z-index: 1;
|
|
144
|
-
padding-left: 0.2rem;
|
|
145
|
-
padding-right: 0.2rem;
|
|
146
|
-
height: 100%;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/* Tooltip text */
|
|
150
|
-
.Tooltip-text {
|
|
151
|
-
/* Center text, add ellipsis */
|
|
152
|
-
overflow: hidden;
|
|
153
|
-
text-align: center;
|
|
154
|
-
text-overflow: ellipsis;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/* Classes to switch between tooltip visible/hidden */
|
|
158
|
-
.Tooltip-tooltip-visible-true {
|
|
159
|
-
opacity: 1;
|
|
160
|
-
}
|
|
161
|
-
.Tooltip-tooltip-visible-false {
|
|
162
|
-
opacity: 0;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/* Classes to switch between tooltip sizes */
|
|
166
|
-
.Tooltip-size-thin {
|
|
167
|
-
width: ${TOOLTIP_WIDTH_THIN_REM}rem;
|
|
168
|
-
left: calc(50% - ${TOOLTIP_WIDTH_THIN_REM / 2}rem);
|
|
169
|
-
}
|
|
170
|
-
.Tooltip-size-normal {
|
|
171
|
-
width: ${TOOLTIP_WIDTH_NORMAL_REM}rem;
|
|
172
|
-
left: calc(50% - ${TOOLTIP_WIDTH_NORMAL_REM / 2}rem);
|
|
173
|
-
}
|
|
174
|
-
.Tooltip-size-wide {
|
|
175
|
-
width: ${TOOLTIP_WIDTH_WIDE_REM}rem;
|
|
176
|
-
left: calc(50% - ${TOOLTIP_WIDTH_WIDE_REM / 2}rem);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/* Arrow (beneath tooltip) */
|
|
180
|
-
.Tooltip-arrow,
|
|
181
|
-
.Tooltip-arrow-shadow {
|
|
182
|
-
/* Position beneath tooltip */
|
|
183
|
-
position: absolute;
|
|
184
|
-
top: -1.5rem;
|
|
185
|
-
font-size: 1.5rem;
|
|
186
|
-
left: calc(50% - 0.5rem);
|
|
187
|
-
width: 0;
|
|
188
|
-
display: inline-block;
|
|
189
|
-
|
|
190
|
-
/* Non-interactive */
|
|
191
|
-
pointer-events: none;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/* Arrow itself */
|
|
195
|
-
.Tooltip-arrow {
|
|
196
|
-
color: black;
|
|
197
|
-
z-index: 4;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/* Arrow shadow */
|
|
201
|
-
.Tooltip-arrow-shadow {
|
|
202
|
-
z-index: -1;
|
|
203
|
-
|
|
204
|
-
/* Blur a white version of the caret as a shadow */
|
|
205
|
-
color: white;
|
|
206
|
-
filter: blur(0.2rem);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/* Classes to switch between arrow visible/hidden */
|
|
210
|
-
.Tooltip-arrow-visible-true {
|
|
211
|
-
opacity: 1;
|
|
212
|
-
}
|
|
213
|
-
.Tooltip-arrow-visible-false {
|
|
214
|
-
opacity: 0;
|
|
215
|
-
}
|
|
216
|
-
`;
|
|
217
|
-
|
|
218
|
-
/*------------------------------------------------------------------------*/
|
|
219
|
-
/* -------------------------------- State ------------------------------- */
|
|
220
|
-
/*------------------------------------------------------------------------*/
|
|
221
|
-
|
|
222
|
-
/* -------- State Definition -------- */
|
|
223
|
-
|
|
224
|
-
type State = {
|
|
225
|
-
// If true, the tooltip is visible
|
|
226
|
-
isVisible: boolean,
|
|
227
|
-
// Number of pixels to nudge the tooltip
|
|
228
|
-
nudgePx: number,
|
|
229
|
-
// If true, bottom left corner of tooltip should not be rounded
|
|
230
|
-
squareBottomLeft?: boolean,
|
|
231
|
-
// If true, bottom right corner of tooltip should not be rounded
|
|
232
|
-
squareBottomRight?: boolean,
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
/* ------------- Actions ------------ */
|
|
236
|
-
|
|
237
|
-
// Types of actions
|
|
238
|
-
enum ActionType {
|
|
239
|
-
// Make the tooltip visible
|
|
240
|
-
Show = 'Show',
|
|
241
|
-
// Make the tooltip invisible
|
|
242
|
-
Hide = 'Hide',
|
|
243
|
-
// Set nudge pixels
|
|
244
|
-
SetNudgePx = 'SetNudgePx',
|
|
245
|
-
// Set whether bottom left corner should be square
|
|
246
|
-
SetSquareBottomLeft = 'SetSquareBottomLeft',
|
|
247
|
-
// Set whether bottom right corner should be square
|
|
248
|
-
SetSquareBottomRight = 'SetSquareBottomRight',
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Action definitions
|
|
252
|
-
type Action = (
|
|
253
|
-
| {
|
|
254
|
-
// Action type
|
|
255
|
-
type: ActionType.SetNudgePx,
|
|
256
|
-
// Number of pixels to nudge the tooltip
|
|
257
|
-
nudgePx: number,
|
|
258
|
-
}
|
|
259
|
-
| {
|
|
260
|
-
// Action type
|
|
261
|
-
type: ActionType.SetSquareBottomLeft,
|
|
262
|
-
// If true, bottom left corner of tooltip should not be rounded
|
|
263
|
-
squareBottomLeft: boolean,
|
|
264
|
-
}
|
|
265
|
-
| {
|
|
266
|
-
// Action type
|
|
267
|
-
type: ActionType.SetSquareBottomRight,
|
|
268
|
-
// If true, bottom right corner of tooltip should not be rounded
|
|
269
|
-
squareBottomRight: boolean,
|
|
270
|
-
}
|
|
271
|
-
| {
|
|
272
|
-
// Action type
|
|
273
|
-
type: (
|
|
274
|
-
| ActionType.Show
|
|
275
|
-
| ActionType.Hide
|
|
276
|
-
),
|
|
277
|
-
}
|
|
278
|
-
);
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Reducer that executes actions
|
|
282
|
-
* @author Gabe Abrams
|
|
283
|
-
* @param state current state
|
|
284
|
-
* @param action action to execute
|
|
285
|
-
*/
|
|
286
|
-
const reducer = (state: State, action: Action): State => {
|
|
287
|
-
switch (action.type) {
|
|
288
|
-
case ActionType.Show: {
|
|
289
|
-
return {
|
|
290
|
-
...state,
|
|
291
|
-
isVisible: true,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
case ActionType.Hide: {
|
|
295
|
-
return {
|
|
296
|
-
...state,
|
|
297
|
-
isVisible: false,
|
|
298
|
-
nudgePx: 0,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
case ActionType.SetNudgePx: {
|
|
302
|
-
return {
|
|
303
|
-
...state,
|
|
304
|
-
nudgePx: action.nudgePx,
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
case ActionType.SetSquareBottomLeft: {
|
|
308
|
-
return {
|
|
309
|
-
...state,
|
|
310
|
-
squareBottomLeft: action.squareBottomLeft,
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
case ActionType.SetSquareBottomRight: {
|
|
314
|
-
return {
|
|
315
|
-
...state,
|
|
316
|
-
squareBottomRight: action.squareBottomRight,
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
default: {
|
|
320
|
-
return state;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
21
|
+
children: JSX.Element,
|
|
323
22
|
};
|
|
324
23
|
|
|
325
24
|
/*------------------------------------------------------------------------*/
|
|
@@ -335,38 +34,14 @@ const Tooltip: React.FC<Props> = (props) => {
|
|
|
335
34
|
|
|
336
35
|
// Destructure all props
|
|
337
36
|
const {
|
|
338
|
-
icon,
|
|
339
37
|
text,
|
|
340
38
|
children,
|
|
341
|
-
wide,
|
|
342
|
-
thin,
|
|
343
|
-
containerIsDisplayBlock,
|
|
344
39
|
} = props;
|
|
345
40
|
|
|
346
|
-
/* -------------- State ------------- */
|
|
347
|
-
|
|
348
|
-
// Initial state
|
|
349
|
-
const initialState: State = {
|
|
350
|
-
isVisible: false,
|
|
351
|
-
nudgePx: 0,
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
// Initialize state
|
|
355
|
-
const [state, dispatch] = useReducer(reducer, initialState);
|
|
356
|
-
|
|
357
|
-
// Destructure common state
|
|
358
|
-
const {
|
|
359
|
-
isVisible,
|
|
360
|
-
nudgePx,
|
|
361
|
-
squareBottomLeft,
|
|
362
|
-
squareBottomRight,
|
|
363
|
-
} = state;
|
|
364
|
-
|
|
365
41
|
/* -------------- Refs -------------- */
|
|
366
42
|
|
|
367
|
-
//
|
|
368
|
-
const
|
|
369
|
-
const arrowElement = useRef<HTMLDivElement | null>(null);
|
|
43
|
+
// Child ref
|
|
44
|
+
const childRef = useRef<Element>(undefined as unknown as Element);
|
|
370
45
|
|
|
371
46
|
/*------------------------------------------------------------------------*/
|
|
372
47
|
/* ------------------------- Lifecycle Functions ------------------------ */
|
|
@@ -378,72 +53,27 @@ const Tooltip: React.FC<Props> = (props) => {
|
|
|
378
53
|
*/
|
|
379
54
|
useEffect(
|
|
380
55
|
() => {
|
|
381
|
-
//
|
|
382
|
-
if (
|
|
383
|
-
|
|
384
|
-
const tooltipContainerRect = (
|
|
385
|
-
tooltipContainer
|
|
386
|
-
.current
|
|
387
|
-
.getBoundingClientRect()
|
|
388
|
-
);
|
|
389
|
-
|
|
390
|
-
// Get the window width
|
|
391
|
-
const windowWidth = window.innerWidth;
|
|
392
|
-
|
|
393
|
-
// Calculate new nudge value
|
|
394
|
-
let newNudgePx: number;
|
|
395
|
-
if (tooltipContainerRect.left < 0) {
|
|
396
|
-
// Tooltip is off the left side of the screen
|
|
397
|
-
newNudgePx = -1 * tooltipContainerRect.left;
|
|
398
|
-
} else if (tooltipContainerRect.right > windowWidth) {
|
|
399
|
-
// Tooltip is off the right side of the screen
|
|
400
|
-
newNudgePx = -1 * (tooltipContainerRect.right - windowWidth);
|
|
401
|
-
} else {
|
|
402
|
-
// Tooltip is in the middle of the screen
|
|
403
|
-
newNudgePx = 0;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// Update state
|
|
407
|
-
dispatch({
|
|
408
|
-
type: ActionType.SetNudgePx,
|
|
409
|
-
nudgePx: newNudgePx,
|
|
410
|
-
});
|
|
56
|
+
// Skip if no child
|
|
57
|
+
if (!childRef.current) {
|
|
58
|
+
return;
|
|
411
59
|
}
|
|
412
60
|
|
|
413
|
-
//
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
// Set bottom left corner rounding
|
|
429
|
-
dispatch({
|
|
430
|
-
type: ActionType.SetSquareBottomLeft,
|
|
431
|
-
squareBottomLeft: (
|
|
432
|
-
arrowRect.left < (TOOLTIP_BORDER_RADIUS_REM * remInPixels)
|
|
433
|
-
),
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
// Set bottom right corner rounding
|
|
437
|
-
dispatch({
|
|
438
|
-
type: ActionType.SetSquareBottomRight,
|
|
439
|
-
squareBottomRight: (
|
|
440
|
-
arrowRect.right
|
|
441
|
-
> window.innerWidth - (TOOLTIP_BORDER_RADIUS_REM * remInPixels)
|
|
442
|
-
),
|
|
443
|
-
});
|
|
444
|
-
}
|
|
61
|
+
// Initialize tooltip
|
|
62
|
+
const t = new BSTooltip(
|
|
63
|
+
childRef.current,
|
|
64
|
+
{
|
|
65
|
+
title: text,
|
|
66
|
+
placement: 'top',
|
|
67
|
+
trigger: 'hover',
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// Clean up tooltip
|
|
72
|
+
return () => {
|
|
73
|
+
t.dispose();
|
|
74
|
+
};
|
|
445
75
|
},
|
|
446
|
-
[
|
|
76
|
+
[text],
|
|
447
77
|
);
|
|
448
78
|
|
|
449
79
|
/*------------------------------------------------------------------------*/
|
|
@@ -454,110 +84,10 @@ const Tooltip: React.FC<Props> = (props) => {
|
|
|
454
84
|
/* --------------- Main UI -------------- */
|
|
455
85
|
/*----------------------------------------*/
|
|
456
86
|
|
|
457
|
-
//
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
} else if (thin) {
|
|
462
|
-
size = 'thin';
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// Render
|
|
466
|
-
return (
|
|
467
|
-
<div
|
|
468
|
-
className={`Tooltip-outer-container ${containerIsDisplayBlock ? 'd-block' : 'd-inline-block'}}`}
|
|
469
|
-
aria-label={text}
|
|
470
|
-
onMouseEnter={() => {
|
|
471
|
-
dispatch({
|
|
472
|
-
type: ActionType.Show,
|
|
473
|
-
});
|
|
474
|
-
}}
|
|
475
|
-
onMouseLeave={() => {
|
|
476
|
-
dispatch({
|
|
477
|
-
type: ActionType.Hide,
|
|
478
|
-
});
|
|
479
|
-
}}
|
|
480
|
-
onFocus={() => {
|
|
481
|
-
dispatch({
|
|
482
|
-
type: ActionType.Show,
|
|
483
|
-
});
|
|
484
|
-
}}
|
|
485
|
-
onBlur={() => {
|
|
486
|
-
dispatch({
|
|
487
|
-
type: ActionType.Hide,
|
|
488
|
-
});
|
|
489
|
-
}}
|
|
490
|
-
>
|
|
491
|
-
{/* Style */}
|
|
492
|
-
<style>
|
|
493
|
-
{style}
|
|
494
|
-
</style>
|
|
495
|
-
|
|
496
|
-
{/* Children */}
|
|
497
|
-
{children}
|
|
498
|
-
|
|
499
|
-
{/* Arrow */}
|
|
500
|
-
<div
|
|
501
|
-
className={`Tooltip-arrow Tooltip-arrow-visible-${isVisible ? 'true' : 'false'}`}
|
|
502
|
-
ref={arrowElement}
|
|
503
|
-
>
|
|
504
|
-
<FontAwesomeIcon
|
|
505
|
-
icon={faCaretDown}
|
|
506
|
-
/>
|
|
507
|
-
</div>
|
|
508
|
-
<div className={`Tooltip-arrow-shadow Tooltip-arrow-visible-${isVisible ? 'true' : 'false'}`}>
|
|
509
|
-
<FontAwesomeIcon
|
|
510
|
-
icon={faCaretDown}
|
|
511
|
-
/>
|
|
512
|
-
</div>
|
|
513
|
-
|
|
514
|
-
{/* Tooltip */}
|
|
515
|
-
<div
|
|
516
|
-
className="Tooltip-tooltip-container"
|
|
517
|
-
>
|
|
518
|
-
<div
|
|
519
|
-
className={`Tooltip-tooltip Tooltip-tooltip-visible-${isVisible ? 'true' : 'false'} Tooltip-size-${size}`}
|
|
520
|
-
role="tooltip"
|
|
521
|
-
ref={tooltipContainer}
|
|
522
|
-
style={{
|
|
523
|
-
transform: `translateX(${nudgePx}px)`,
|
|
524
|
-
}}
|
|
525
|
-
>
|
|
526
|
-
{/* Box */}
|
|
527
|
-
<div className="Tooltip-box-highlight" />
|
|
528
|
-
<div
|
|
529
|
-
className="Tooltip-box"
|
|
530
|
-
style={{
|
|
531
|
-
borderBottomLeftRadius: squareBottomLeft ? 0 : undefined,
|
|
532
|
-
borderBottomRightRadius: squareBottomRight ? 0 : undefined,
|
|
533
|
-
}}
|
|
534
|
-
/>
|
|
535
|
-
<div
|
|
536
|
-
className="Tooltip-box-shadow"
|
|
537
|
-
style={{
|
|
538
|
-
borderBottomLeftRadius: squareBottomLeft ? 0 : undefined,
|
|
539
|
-
borderBottomRightRadius: squareBottomRight ? 0 : undefined,
|
|
540
|
-
}}
|
|
541
|
-
/>
|
|
542
|
-
|
|
543
|
-
{/* Contents */}
|
|
544
|
-
<div className="Tooltip-contents">
|
|
545
|
-
{/* Icon */}
|
|
546
|
-
{icon && (
|
|
547
|
-
<FontAwesomeIcon
|
|
548
|
-
icon={icon}
|
|
549
|
-
className="me-1"
|
|
550
|
-
/>
|
|
551
|
-
)}
|
|
552
|
-
|
|
553
|
-
{/* Text */}
|
|
554
|
-
<span className="Tooltip-text">
|
|
555
|
-
{text}
|
|
556
|
-
</span>
|
|
557
|
-
</div>
|
|
558
|
-
</div>
|
|
559
|
-
</div>
|
|
560
|
-
</div>
|
|
87
|
+
// Clone child and add ref
|
|
88
|
+
return React.cloneElement(
|
|
89
|
+
children,
|
|
90
|
+
{ ref: childRef },
|
|
561
91
|
);
|
|
562
92
|
};
|
|
563
93
|
|