@myzbox/react-overlay 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.
- package/LICENSE +21 -0
- package/README.md +457 -0
- package/dist/index.d.ts +1 -0
- package/dist/react-overlay.css +1 -0
- package/dist/react-overlay.es.js +865 -0
- package/dist/react-overlay.umd.js +26 -0
- package/package.json +85 -0
- package/src/components/index.ts +11 -0
- package/src/components/modal/Modal.tsx +186 -0
- package/src/components/modal-variants/AlertModal.tsx +56 -0
- package/src/components/modal-variants/ConfirmModal.tsx +78 -0
- package/src/components/modal-variants/Drawer.tsx +51 -0
- package/src/components/popover/Popover.tsx +54 -0
- package/src/components/toast/Toast.tsx +61 -0
- package/src/components/toast/ToastProvider.tsx +71 -0
- package/src/components/toast/index.ts +3 -0
- package/src/components/toast/useToast.ts +48 -0
- package/src/components/tooltip/Tooltip.tsx +52 -0
- package/src/hooks/useClickOutside.ts +24 -0
- package/src/hooks/useDraggable.ts +75 -0
- package/src/hooks/useModal.ts +23 -0
- package/src/index.ts +8 -0
- package/src/styles/Modal.module.css +314 -0
- package/src/styles/ModalVariants.module.css +132 -0
- package/src/styles/Popover.module.css +70 -0
- package/src/styles/Toast.module.css +196 -0
- package/src/styles/Tooltip.module.css +50 -0
- package/src/styles/index.css +5 -0
- package/src/types/Modal.ts +100 -0
- package/src/types/Popover.ts +13 -0
- package/src/types/Toast.ts +19 -0
- package/src/types/Tooltip.ts +19 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--rm-success-bg: #d1fae5;
|
|
3
|
+
--rm-success-color: #065f46;
|
|
4
|
+
--rm-error-bg: #fee2e2;
|
|
5
|
+
--rm-error-color: #991b1b;
|
|
6
|
+
--rm-warning-bg: #fef3c7;
|
|
7
|
+
--rm-warning-color: #92400e;
|
|
8
|
+
--rm-info-bg: #dbeafe;
|
|
9
|
+
--rm-info-color: #1e40af;
|
|
10
|
+
|
|
11
|
+
--rm-btn-primary-bg: #2563eb;
|
|
12
|
+
--rm-btn-primary-hover: #1d4ed8;
|
|
13
|
+
--rm-btn-primary-text: #ffffff;
|
|
14
|
+
|
|
15
|
+
--rm-btn-default-bg: #ffffff;
|
|
16
|
+
--rm-btn-default-border: #d1d5db;
|
|
17
|
+
--rm-btn-default-text: #374151;
|
|
18
|
+
--rm-btn-default-hover: #f3f4f6;
|
|
19
|
+
|
|
20
|
+
--rm-btn-destructive-bg: #dc2626;
|
|
21
|
+
--rm-btn-destructive-hover: #b91c1c;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.drawer {
|
|
25
|
+
border-radius: 0;
|
|
26
|
+
max-height: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.drawer.left,
|
|
30
|
+
.drawer.right {
|
|
31
|
+
height: 100vh;
|
|
32
|
+
border-radius: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.drawer.top,
|
|
36
|
+
.drawer.bottom {
|
|
37
|
+
width: 100vw;
|
|
38
|
+
border-radius: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.alertModal {
|
|
42
|
+
box-sizing: border-box;
|
|
43
|
+
display: block;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
.alertContent {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: 1rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.icon {
|
|
54
|
+
width: 2rem;
|
|
55
|
+
height: 2rem;
|
|
56
|
+
border-radius: 50%;
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
font-weight: bold;
|
|
61
|
+
flex-shrink: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.success .icon {
|
|
65
|
+
background: var(--rm-success-bg);
|
|
66
|
+
color: var(--rm-success-color);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.error .icon {
|
|
70
|
+
background: var(--rm-error-bg);
|
|
71
|
+
color: var(--rm-error-color);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.warning .icon {
|
|
75
|
+
background: var(--rm-warning-bg);
|
|
76
|
+
color: var(--rm-warning-color);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.info .icon {
|
|
80
|
+
background: var(--rm-info-bg);
|
|
81
|
+
color: var(--rm-info-color);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.okButton,
|
|
85
|
+
.confirmButton {
|
|
86
|
+
box-sizing: border-box;
|
|
87
|
+
background: var(--rm-btn-primary-bg);
|
|
88
|
+
color: var(--rm-btn-primary-text);
|
|
89
|
+
border: none;
|
|
90
|
+
padding: 0.5rem 1rem;
|
|
91
|
+
border-radius: 4px;
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
font-weight: 500;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.okButton:hover,
|
|
97
|
+
.confirmButton:hover {
|
|
98
|
+
background: var(--rm-btn-primary-hover);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.okButton:disabled,
|
|
102
|
+
.confirmButton:disabled {
|
|
103
|
+
opacity: 0.5;
|
|
104
|
+
cursor: not-allowed;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.cancelButton {
|
|
108
|
+
box-sizing: border-box;
|
|
109
|
+
background: var(--rm-btn-default-bg);
|
|
110
|
+
border: 1px solid var(--rm-btn-default-border);
|
|
111
|
+
color: var(--rm-btn-default-text);
|
|
112
|
+
padding: 0.5rem 1rem;
|
|
113
|
+
border-radius: 4px;
|
|
114
|
+
cursor: pointer;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.cancelButton:hover {
|
|
118
|
+
background: var(--rm-btn-default-hover);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.cancelButton:disabled {
|
|
122
|
+
opacity: 0.5;
|
|
123
|
+
cursor: not-allowed;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.destructive {
|
|
127
|
+
background: var(--rm-btn-destructive-bg);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.destructive:hover {
|
|
131
|
+
background: var(--rm-btn-destructive-hover);
|
|
132
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
.wrapper {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-block;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.trigger {
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
display: inline-block;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.popover {
|
|
12
|
+
position: absolute;
|
|
13
|
+
background-color: white;
|
|
14
|
+
color: #374151;
|
|
15
|
+
padding: 1rem;
|
|
16
|
+
border-radius: 8px;
|
|
17
|
+
border: 1px solid #e5e7eb;
|
|
18
|
+
z-index: 900;
|
|
19
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
20
|
+
min-width: 200px;
|
|
21
|
+
animation: fadeIn 0.15s ease-out;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.popover.draggable {
|
|
25
|
+
cursor: move;
|
|
26
|
+
user-select: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Positions */
|
|
30
|
+
.popover.bottom {
|
|
31
|
+
top: calc(100% + 0.5rem);
|
|
32
|
+
left: 50%;
|
|
33
|
+
transform: translateX(-50%);
|
|
34
|
+
transform-origin: top center;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.popover.top {
|
|
38
|
+
bottom: calc(100% + 0.5rem);
|
|
39
|
+
left: 50%;
|
|
40
|
+
transform: translateX(-50%);
|
|
41
|
+
transform-origin: bottom center;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.popover.left {
|
|
45
|
+
right: calc(100% + 0.5rem);
|
|
46
|
+
top: 50%;
|
|
47
|
+
transform: translateY(-50%);
|
|
48
|
+
transform-origin: center right;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.popover.right {
|
|
52
|
+
left: calc(100% + 0.5rem);
|
|
53
|
+
top: 50%;
|
|
54
|
+
transform: translateY(-50%);
|
|
55
|
+
transform-origin: center left;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@keyframes fadeIn {
|
|
59
|
+
from {
|
|
60
|
+
opacity: 0;
|
|
61
|
+
transform: scale(0.95);
|
|
62
|
+
margin-top: -5px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
to {
|
|
66
|
+
opacity: 1;
|
|
67
|
+
transform: scale(1);
|
|
68
|
+
margin-top: 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
.toast {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: 12px;
|
|
5
|
+
min-width: 300px;
|
|
6
|
+
max-width: 400px;
|
|
7
|
+
padding: 12px 16px;
|
|
8
|
+
border-radius: 6px;
|
|
9
|
+
background: white;
|
|
10
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
11
|
+
margin-bottom: 10px;
|
|
12
|
+
pointer-events: auto;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
animation: slideIn 0.3s ease-out;
|
|
15
|
+
transition: all 0.3s ease-in-out;
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.toast.draggable {
|
|
20
|
+
cursor: move;
|
|
21
|
+
user-select: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.toast.exiting {
|
|
25
|
+
opacity: 0;
|
|
26
|
+
transform: scale(0.95);
|
|
27
|
+
margin-bottom: -40px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Types */
|
|
31
|
+
.toast.success {
|
|
32
|
+
border-left: 4px solid #10b981;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.toast.error {
|
|
36
|
+
border-left: 4px solid #ef4444;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.toast.warning {
|
|
40
|
+
border-left: 4px solid #f59e0b;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.toast.info {
|
|
44
|
+
border-left: 4px solid #3b82f6;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.icon {
|
|
48
|
+
font-weight: bold;
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
justify-content: center;
|
|
52
|
+
width: 28px;
|
|
53
|
+
height: 28px;
|
|
54
|
+
border-radius: 50%;
|
|
55
|
+
flex-shrink: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.toast.success .icon {
|
|
59
|
+
background-color: #ecfdf5;
|
|
60
|
+
color: #059669;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.toast.error .icon {
|
|
64
|
+
background-color: #fef2f2;
|
|
65
|
+
color: #dc2626;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.toast.warning .icon {
|
|
69
|
+
background-color: #fffbeb;
|
|
70
|
+
color: #d97706;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.toast.info .icon {
|
|
74
|
+
background-color: #eff6ff;
|
|
75
|
+
color: #2563eb;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.content {
|
|
79
|
+
flex: 1;
|
|
80
|
+
font-size: 14px;
|
|
81
|
+
color: #374151;
|
|
82
|
+
line-height: 1.4;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.closeBtn {
|
|
86
|
+
background: transparent;
|
|
87
|
+
border: none;
|
|
88
|
+
cursor: pointer;
|
|
89
|
+
font-size: 18px;
|
|
90
|
+
color: #4b5563;
|
|
91
|
+
padding: 0;
|
|
92
|
+
display: flex;
|
|
93
|
+
font-weight: 700;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
96
|
+
width: 24px;
|
|
97
|
+
height: 24px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.closeBtn:hover {
|
|
101
|
+
color: #111827;
|
|
102
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
103
|
+
border-radius: 4px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@keyframes slideIn {
|
|
107
|
+
from {
|
|
108
|
+
opacity: 0;
|
|
109
|
+
transform: translateY(10px);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
to {
|
|
113
|
+
opacity: 1;
|
|
114
|
+
transform: translateY(0);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Container Styles */
|
|
119
|
+
.container {
|
|
120
|
+
position: fixed;
|
|
121
|
+
z-index: 9999;
|
|
122
|
+
pointer-events: none;
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-direction: column;
|
|
125
|
+
padding: 16px;
|
|
126
|
+
gap: 8px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.container.top-left {
|
|
130
|
+
top: 0;
|
|
131
|
+
left: 0;
|
|
132
|
+
align-items: flex-start;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.container.top-right {
|
|
136
|
+
top: 0;
|
|
137
|
+
right: 0;
|
|
138
|
+
align-items: flex-end;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.container.top-center {
|
|
142
|
+
top: 0;
|
|
143
|
+
left: 50%;
|
|
144
|
+
transform: translateX(-50%);
|
|
145
|
+
align-items: center;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.container.bottom-left {
|
|
149
|
+
bottom: 0;
|
|
150
|
+
left: 0;
|
|
151
|
+
align-items: flex-start;
|
|
152
|
+
flex-direction: column-reverse;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.container.bottom-right {
|
|
156
|
+
bottom: 0;
|
|
157
|
+
right: 0;
|
|
158
|
+
align-items: flex-end;
|
|
159
|
+
flex-direction: column-reverse;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.container.bottom-center {
|
|
163
|
+
bottom: 0;
|
|
164
|
+
left: 50%;
|
|
165
|
+
transform: translateX(-50%);
|
|
166
|
+
align-items: center;
|
|
167
|
+
flex-direction: column-reverse;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Animation adjustments based on position */
|
|
171
|
+
.container.bottom-left .toast,
|
|
172
|
+
.container.bottom-right .toast,
|
|
173
|
+
.container.bottom-center .toast {
|
|
174
|
+
margin-bottom: 0;
|
|
175
|
+
margin-top: 10px;
|
|
176
|
+
animation: slideInBottom 0.3s ease-out;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.container.bottom-left .toast.exiting,
|
|
180
|
+
.container.bottom-right .toast.exiting,
|
|
181
|
+
.container.bottom-center .toast.exiting {
|
|
182
|
+
margin-top: -40px;
|
|
183
|
+
margin-bottom: 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@keyframes slideInBottom {
|
|
187
|
+
from {
|
|
188
|
+
opacity: 0;
|
|
189
|
+
transform: translateY(-10px);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
to {
|
|
193
|
+
opacity: 1;
|
|
194
|
+
transform: translateY(0);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
.wrapper {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-block;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.tooltip {
|
|
7
|
+
position: absolute;
|
|
8
|
+
background-color: #111827;
|
|
9
|
+
color: white;
|
|
10
|
+
padding: 0.5rem 0.75rem;
|
|
11
|
+
border-radius: 4px;
|
|
12
|
+
font-size: 0.875rem;
|
|
13
|
+
z-index: 1000;
|
|
14
|
+
white-space: nowrap;
|
|
15
|
+
pointer-events: none;
|
|
16
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
17
|
+
opacity: 0;
|
|
18
|
+
animation: fadeIn 0.2s forwards;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Positions */
|
|
22
|
+
.tooltip.top {
|
|
23
|
+
bottom: 100%;
|
|
24
|
+
left: 50%;
|
|
25
|
+
transform: translateX(-50%) translateY(-0.5rem);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.tooltip.bottom {
|
|
29
|
+
top: 100%;
|
|
30
|
+
left: 50%;
|
|
31
|
+
transform: translateX(-50%) translateY(0.5rem);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.tooltip.left {
|
|
35
|
+
right: 100%;
|
|
36
|
+
top: 50%;
|
|
37
|
+
transform: translateY(-50%) translateX(-0.5rem);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.tooltip.right {
|
|
41
|
+
left: 100%;
|
|
42
|
+
top: 50%;
|
|
43
|
+
transform: translateY(-50%) translateX(0.5rem);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@keyframes fadeIn {
|
|
47
|
+
to {
|
|
48
|
+
opacity: 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ReactNode, RefObject, CSSProperties } from 'react';
|
|
2
|
+
|
|
3
|
+
export type ModalPosition =
|
|
4
|
+
| 'center'
|
|
5
|
+
| 'top'
|
|
6
|
+
| 'bottom'
|
|
7
|
+
| 'left'
|
|
8
|
+
| 'right'
|
|
9
|
+
| 'top-left'
|
|
10
|
+
| 'top-right'
|
|
11
|
+
| 'bottom-left'
|
|
12
|
+
| 'bottom-right';
|
|
13
|
+
|
|
14
|
+
export type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'auto';
|
|
15
|
+
|
|
16
|
+
export type ModalAnimation = 'zoom' | 'fade' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'drawer-slide-left' | 'drawer-slide-right' | 'drawer-slide-up' | 'drawer-slide-down' | 'none';
|
|
17
|
+
|
|
18
|
+
export interface ModalProps {
|
|
19
|
+
/**
|
|
20
|
+
* Controls the visibility of the modal.
|
|
21
|
+
*/
|
|
22
|
+
isOpen: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Callback fired when the modal requests to be closed.
|
|
25
|
+
*/
|
|
26
|
+
onClose: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Content to return inside the modal.
|
|
29
|
+
*/
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* Modal title (optional).
|
|
33
|
+
*/
|
|
34
|
+
title?: ReactNode;
|
|
35
|
+
/**
|
|
36
|
+
* Modal footer content (optional).
|
|
37
|
+
*/
|
|
38
|
+
footer?: ReactNode;
|
|
39
|
+
/**
|
|
40
|
+
* Whether to close the modal when clicking on the overlay.
|
|
41
|
+
* @default true
|
|
42
|
+
*/
|
|
43
|
+
closeOnOverlayClick?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Whether to close the modal when pressing the Escape key.
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
closeOnEsc?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Additional class name for the overlay.
|
|
51
|
+
*/
|
|
52
|
+
overlayClassName?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Additional class name for the modal content container.
|
|
55
|
+
*/
|
|
56
|
+
className?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Inline styles for the overlay.
|
|
59
|
+
*/
|
|
60
|
+
overlayStyle?: CSSProperties;
|
|
61
|
+
/**
|
|
62
|
+
* Inline styles for the content.
|
|
63
|
+
*/
|
|
64
|
+
style?: CSSProperties;
|
|
65
|
+
/**
|
|
66
|
+
* Position of the modal on the screen.
|
|
67
|
+
* @default 'center'
|
|
68
|
+
*/
|
|
69
|
+
position?: ModalPosition;
|
|
70
|
+
/**
|
|
71
|
+
* Size of the modal.
|
|
72
|
+
* @default 'md'
|
|
73
|
+
*/
|
|
74
|
+
size?: ModalSize;
|
|
75
|
+
/**
|
|
76
|
+
* Animation type.
|
|
77
|
+
* @default 'zoom'
|
|
78
|
+
*/
|
|
79
|
+
animation?: ModalAnimation;
|
|
80
|
+
/**
|
|
81
|
+
* Element to focus when the modal opens.
|
|
82
|
+
*/
|
|
83
|
+
initialFocusRef?: RefObject<HTMLElement | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Element that should remain accessible (not hidden to screen readers) usually root.
|
|
86
|
+
*/
|
|
87
|
+
appElement?: HTMLElement | string;
|
|
88
|
+
/**
|
|
89
|
+
* Z-index override
|
|
90
|
+
*/
|
|
91
|
+
zIndex?: number;
|
|
92
|
+
/**
|
|
93
|
+
* Enable drag functionality
|
|
94
|
+
*/
|
|
95
|
+
draggable?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Whether to hide the header section (title and close button)
|
|
98
|
+
*/
|
|
99
|
+
hideHeader?: boolean;
|
|
100
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export type PopoverPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
4
|
+
|
|
5
|
+
export interface PopoverProps {
|
|
6
|
+
children: ReactNode; // The trigger element
|
|
7
|
+
content: ReactNode | ((close: () => void) => ReactNode); // The popover content
|
|
8
|
+
position?: PopoverPosition;
|
|
9
|
+
className?: string;
|
|
10
|
+
style?: React.CSSProperties;
|
|
11
|
+
width?: string | number;
|
|
12
|
+
draggable?: boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export type ToastType = 'success' | 'error' | 'warning' | 'info';
|
|
4
|
+
export type ToastPosition = 'top-left' | 'top-right' | 'top-center' | 'bottom-left' | 'bottom-right' | 'bottom-center';
|
|
5
|
+
|
|
6
|
+
export interface ToastOptions {
|
|
7
|
+
id: string;
|
|
8
|
+
type: ToastType;
|
|
9
|
+
content: ReactNode;
|
|
10
|
+
duration?: number; // ms, if 0 then no auto-close
|
|
11
|
+
delay?: number; // ms, wait before showing
|
|
12
|
+
position?: ToastPosition;
|
|
13
|
+
draggable?: boolean;
|
|
14
|
+
onClose?: () => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ToastProps extends ToastOptions {
|
|
18
|
+
onDismiss: (id: string) => void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
4
|
+
|
|
5
|
+
export interface TooltipProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
content: ReactNode;
|
|
8
|
+
position?: TooltipPosition;
|
|
9
|
+
delay?: number;
|
|
10
|
+
width?: string | number;
|
|
11
|
+
height?: string | number;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: React.CSSProperties;
|
|
14
|
+
/**
|
|
15
|
+
* By default, tooltips may clip if parent has overflow:hidden.
|
|
16
|
+
* Using a portal avoids this but adds complexity.
|
|
17
|
+
* For this implementation, we'll keep it simple first.
|
|
18
|
+
*/
|
|
19
|
+
}
|