@donkit-ai/design-system 0.2.5 → 0.2.7
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/package.json +1 -1
- package/src/components/Alert.css +4 -4
- package/src/components/Tooltip.css +134 -0
- package/src/components/Tooltip.jsx +75 -0
- package/src/index.js +1 -0
package/package.json
CHANGED
package/src/components/Alert.css
CHANGED
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
|
|
59
59
|
/* Variants */
|
|
60
60
|
.ds-alert--info {
|
|
61
|
-
background-color
|
|
61
|
+
background: linear-gradient(var(--color-status-info-bg), var(--color-status-info-bg)), var(--color-bg);
|
|
62
62
|
border-color: var(--color-status-info);
|
|
63
63
|
color: var(--color-status-info);
|
|
64
64
|
}
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
.ds-alert--success {
|
|
71
|
-
background-color
|
|
71
|
+
background: linear-gradient(var(--color-status-success-bg), var(--color-status-success-bg)), var(--color-bg);
|
|
72
72
|
border-color: var(--color-status-success);
|
|
73
73
|
color: var(--color-status-success);
|
|
74
74
|
}
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
.ds-alert--warning {
|
|
81
|
-
background-color
|
|
81
|
+
background: linear-gradient(var(--color-status-warning-bg), var(--color-status-warning-bg)), var(--color-bg);
|
|
82
82
|
border-color: var(--color-status-warning);
|
|
83
83
|
color: var(--color-status-warning);
|
|
84
84
|
}
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
.ds-alert--error {
|
|
91
|
-
background-color
|
|
91
|
+
background: linear-gradient(var(--color-status-error-bg), var(--color-status-error-bg)), var(--color-bg);
|
|
92
92
|
border-color: var(--color-status-error);
|
|
93
93
|
color: var(--color-status-error);
|
|
94
94
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
.ds-tooltip-wrapper {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.ds-tooltip {
|
|
7
|
+
position: absolute;
|
|
8
|
+
background-color: var(--color-bg);
|
|
9
|
+
color: var(--color-txt-icon-2);
|
|
10
|
+
font-size: var(--font-size-p3);
|
|
11
|
+
letter-spacing: var(--letter-spacing-p3);
|
|
12
|
+
width: max-content;
|
|
13
|
+
max-width: 200px;
|
|
14
|
+
padding: var(--space-xs);
|
|
15
|
+
border: 1px solid var(--color-border);
|
|
16
|
+
border-radius: var(--radius-xs);
|
|
17
|
+
z-index: 2000;
|
|
18
|
+
white-space: normal;
|
|
19
|
+
word-wrap: break-word;
|
|
20
|
+
pointer-events: none;
|
|
21
|
+
line-height: 1.4;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Position: Top */
|
|
25
|
+
.ds-tooltip--top {
|
|
26
|
+
bottom: calc(100% + 8px);
|
|
27
|
+
left: 50%;
|
|
28
|
+
transform: translateX(-50%);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ds-tooltip--top::after {
|
|
32
|
+
content: '';
|
|
33
|
+
position: absolute;
|
|
34
|
+
top: 100%;
|
|
35
|
+
left: 50%;
|
|
36
|
+
transform: translateX(-50%);
|
|
37
|
+
border: 4px solid transparent;
|
|
38
|
+
border-top-color: var(--color-border);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.ds-tooltip--top::before {
|
|
42
|
+
content: '';
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 100%;
|
|
45
|
+
left: 50%;
|
|
46
|
+
transform: translateX(-50%);
|
|
47
|
+
border: 3px solid transparent;
|
|
48
|
+
border-top-color: var(--color-bg);
|
|
49
|
+
z-index: 1;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Position: Bottom */
|
|
53
|
+
.ds-tooltip--bottom {
|
|
54
|
+
top: calc(100% + 8px);
|
|
55
|
+
left: 50%;
|
|
56
|
+
transform: translateX(-50%);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ds-tooltip--bottom::after {
|
|
60
|
+
content: '';
|
|
61
|
+
position: absolute;
|
|
62
|
+
bottom: 100%;
|
|
63
|
+
left: 50%;
|
|
64
|
+
transform: translateX(-50%);
|
|
65
|
+
border: 4px solid transparent;
|
|
66
|
+
border-bottom-color: var(--color-border);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.ds-tooltip--bottom::before {
|
|
70
|
+
content: '';
|
|
71
|
+
position: absolute;
|
|
72
|
+
bottom: 100%;
|
|
73
|
+
left: 50%;
|
|
74
|
+
transform: translateX(-50%);
|
|
75
|
+
border: 3px solid transparent;
|
|
76
|
+
border-bottom-color: var(--color-bg);
|
|
77
|
+
z-index: 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Position: Left */
|
|
81
|
+
.ds-tooltip--left {
|
|
82
|
+
right: calc(100% + 8px);
|
|
83
|
+
top: 50%;
|
|
84
|
+
transform: translateY(-50%);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ds-tooltip--left::after {
|
|
88
|
+
content: '';
|
|
89
|
+
position: absolute;
|
|
90
|
+
left: 100%;
|
|
91
|
+
top: 50%;
|
|
92
|
+
transform: translateY(-50%);
|
|
93
|
+
border: 4px solid transparent;
|
|
94
|
+
border-left-color: var(--color-border);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.ds-tooltip--left::before {
|
|
98
|
+
content: '';
|
|
99
|
+
position: absolute;
|
|
100
|
+
left: 100%;
|
|
101
|
+
top: 50%;
|
|
102
|
+
transform: translateY(-50%);
|
|
103
|
+
border: 3px solid transparent;
|
|
104
|
+
border-left-color: var(--color-bg);
|
|
105
|
+
z-index: 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Position: Right */
|
|
109
|
+
.ds-tooltip--right {
|
|
110
|
+
left: calc(100% + 8px);
|
|
111
|
+
top: 50%;
|
|
112
|
+
transform: translateY(-50%);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.ds-tooltip--right::after {
|
|
116
|
+
content: '';
|
|
117
|
+
position: absolute;
|
|
118
|
+
right: 100%;
|
|
119
|
+
top: 50%;
|
|
120
|
+
transform: translateY(-50%);
|
|
121
|
+
border: 4px solid transparent;
|
|
122
|
+
border-right-color: var(--color-border);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.ds-tooltip--right::before {
|
|
126
|
+
content: '';
|
|
127
|
+
position: absolute;
|
|
128
|
+
right: 100%;
|
|
129
|
+
top: 50%;
|
|
130
|
+
transform: translateY(-50%);
|
|
131
|
+
border: 3px solid transparent;
|
|
132
|
+
border-right-color: var(--color-bg);
|
|
133
|
+
z-index: 1;
|
|
134
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
+
import './Tooltip.css';
|
|
3
|
+
|
|
4
|
+
export function Tooltip({
|
|
5
|
+
children,
|
|
6
|
+
content,
|
|
7
|
+
position,
|
|
8
|
+
...props
|
|
9
|
+
}) {
|
|
10
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
11
|
+
const [computedPosition, setComputedPosition] = useState(position || 'top');
|
|
12
|
+
const wrapperRef = useRef(null);
|
|
13
|
+
const tooltipRef = useRef(null);
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (isVisible && !position && wrapperRef.current && tooltipRef.current) {
|
|
17
|
+
const wrapperRect = wrapperRef.current.getBoundingClientRect();
|
|
18
|
+
const tooltipRect = tooltipRef.current.getBoundingClientRect();
|
|
19
|
+
const viewportHeight = window.innerHeight;
|
|
20
|
+
const viewportWidth = window.innerWidth;
|
|
21
|
+
|
|
22
|
+
// Calculate available space in each direction
|
|
23
|
+
const spaceTop = wrapperRect.top;
|
|
24
|
+
const spaceBottom = viewportHeight - wrapperRect.bottom;
|
|
25
|
+
const spaceLeft = wrapperRect.left;
|
|
26
|
+
const spaceRight = viewportWidth - wrapperRect.right;
|
|
27
|
+
|
|
28
|
+
const tooltipHeight = tooltipRect.height;
|
|
29
|
+
const tooltipWidth = tooltipRect.width;
|
|
30
|
+
|
|
31
|
+
// Prefer top/bottom first, then left/right
|
|
32
|
+
if (spaceTop >= tooltipHeight + 8) {
|
|
33
|
+
setComputedPosition('top');
|
|
34
|
+
} else if (spaceBottom >= tooltipHeight + 8) {
|
|
35
|
+
setComputedPosition('bottom');
|
|
36
|
+
} else if (spaceRight >= tooltipWidth + 8) {
|
|
37
|
+
setComputedPosition('right');
|
|
38
|
+
} else if (spaceLeft >= tooltipWidth + 8) {
|
|
39
|
+
setComputedPosition('left');
|
|
40
|
+
} else {
|
|
41
|
+
// Fallback to direction with most space
|
|
42
|
+
const maxSpace = Math.max(spaceTop, spaceBottom, spaceLeft, spaceRight);
|
|
43
|
+
if (maxSpace === spaceTop) setComputedPosition('top');
|
|
44
|
+
else if (maxSpace === spaceBottom) setComputedPosition('bottom');
|
|
45
|
+
else if (maxSpace === spaceRight) setComputedPosition('right');
|
|
46
|
+
else setComputedPosition('left');
|
|
47
|
+
}
|
|
48
|
+
} else if (position) {
|
|
49
|
+
setComputedPosition(position);
|
|
50
|
+
}
|
|
51
|
+
}, [isVisible, position]);
|
|
52
|
+
|
|
53
|
+
if (!content) return children;
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div
|
|
57
|
+
ref={wrapperRef}
|
|
58
|
+
className="ds-tooltip-wrapper"
|
|
59
|
+
onMouseEnter={() => setIsVisible(true)}
|
|
60
|
+
onMouseLeave={() => setIsVisible(false)}
|
|
61
|
+
{...props}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
{isVisible && (
|
|
65
|
+
<div
|
|
66
|
+
ref={tooltipRef}
|
|
67
|
+
className={`ds-tooltip ds-tooltip--${computedPosition}`}
|
|
68
|
+
role="tooltip"
|
|
69
|
+
>
|
|
70
|
+
{content}
|
|
71
|
+
</div>
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
package/src/index.js
CHANGED