mertani-web-toolkit 0.1.66 → 0.1.68
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.
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
interface Props extends Omit<HTMLButtonAttributes, 'type'> {
|
|
8
8
|
// ===Styles===
|
|
9
9
|
type?: 'solid' | 'outline';
|
|
10
|
-
size?: 48 | 40 | 32;
|
|
10
|
+
size?: 48 | 40 | 32 | 24 | 20 | 16;
|
|
11
11
|
backgroundColor?: string;
|
|
12
12
|
textColor?: string;
|
|
13
13
|
borderColor?: string;
|
|
@@ -25,12 +25,16 @@
|
|
|
25
25
|
// Events
|
|
26
26
|
onclick?: () => void;
|
|
27
27
|
onmouseenter?: () => void;
|
|
28
|
+
onmouseleave?: () => void;
|
|
28
29
|
|
|
29
30
|
// Additional Actions
|
|
30
31
|
isLoading?: boolean;
|
|
31
32
|
isShow?: boolean;
|
|
32
33
|
disabled?: boolean;
|
|
33
34
|
tooltip?: string;
|
|
35
|
+
tooltipPosition?: 'top' | 'bottom' | 'left' | 'right' | 'auto';
|
|
36
|
+
tooltipBgColor?: string;
|
|
37
|
+
tooltipTextColor?: string;
|
|
34
38
|
|
|
35
39
|
// Any
|
|
36
40
|
class?: string;
|
|
@@ -53,18 +57,22 @@
|
|
|
53
57
|
|
|
54
58
|
// ===Properties===
|
|
55
59
|
// Data
|
|
56
|
-
label = '
|
|
60
|
+
label = '',
|
|
57
61
|
|
|
58
62
|
// Additional Actions
|
|
59
63
|
isLoading = false,
|
|
60
64
|
isShow = true,
|
|
61
65
|
disabled = false,
|
|
62
66
|
tooltip = '',
|
|
67
|
+
tooltipPosition = 'auto',
|
|
68
|
+
tooltipBgColor = 'var(--color-bg-inverse)',
|
|
69
|
+
tooltipTextColor = 'var(--color-text-inverse)',
|
|
63
70
|
|
|
64
71
|
class: className = '',
|
|
65
72
|
style: customStyle = '',
|
|
66
73
|
onclick,
|
|
67
74
|
onmouseenter,
|
|
75
|
+
onmouseleave,
|
|
68
76
|
...props
|
|
69
77
|
}: Props = $props();
|
|
70
78
|
|
|
@@ -72,13 +80,61 @@
|
|
|
72
80
|
const sizeConfig = $derived(() => {
|
|
73
81
|
switch (size) {
|
|
74
82
|
case 48:
|
|
75
|
-
return {
|
|
83
|
+
return {
|
|
84
|
+
height: '48px',
|
|
85
|
+
width: label ? 'auto' : '48px',
|
|
86
|
+
padding: label ? '10px 24px' : '10px',
|
|
87
|
+
fontSize: '18px',
|
|
88
|
+
borderRadius: '8px'
|
|
89
|
+
};
|
|
76
90
|
case 40:
|
|
77
|
-
return {
|
|
91
|
+
return {
|
|
92
|
+
height: '40px',
|
|
93
|
+
width: label ? 'auto' : '40px',
|
|
94
|
+
padding: label ? '8px 16px' : '8px',
|
|
95
|
+
fontSize: '16px',
|
|
96
|
+
borderRadius: '8px'
|
|
97
|
+
};
|
|
78
98
|
case 32:
|
|
79
|
-
return {
|
|
99
|
+
return {
|
|
100
|
+
height: '32px',
|
|
101
|
+
width: label ? 'auto' : '32px',
|
|
102
|
+
padding: label ? '6px 12px' : '6px',
|
|
103
|
+
fontSize: '14px',
|
|
104
|
+
borderRadius: '6px'
|
|
105
|
+
};
|
|
106
|
+
case 24:
|
|
107
|
+
return {
|
|
108
|
+
height: '24px',
|
|
109
|
+
width: label ? 'auto' : '24px',
|
|
110
|
+
padding: label ? '4px 8px' : '4px',
|
|
111
|
+
fontSize: '12px',
|
|
112
|
+
borderRadius: '4px'
|
|
113
|
+
};
|
|
114
|
+
case 20:
|
|
115
|
+
return {
|
|
116
|
+
height: '20px',
|
|
117
|
+
width: label ? 'auto' : '20px',
|
|
118
|
+
padding: label ? '2px 6px' : '2px',
|
|
119
|
+
fontSize: '10px',
|
|
120
|
+
borderRadius: '4px'
|
|
121
|
+
};
|
|
122
|
+
case 16:
|
|
123
|
+
return {
|
|
124
|
+
height: '16px',
|
|
125
|
+
width: label ? 'auto' : '16px',
|
|
126
|
+
padding: label ? '0px 4px' : '0px',
|
|
127
|
+
fontSize: '10px',
|
|
128
|
+
borderRadius: '4px'
|
|
129
|
+
};
|
|
80
130
|
default:
|
|
81
|
-
return {
|
|
131
|
+
return {
|
|
132
|
+
height: '40px',
|
|
133
|
+
width: label ? 'auto' : '40px',
|
|
134
|
+
padding: label ? '8px 16px' : '8px',
|
|
135
|
+
fontSize: '16px',
|
|
136
|
+
borderRadius: '8px'
|
|
137
|
+
};
|
|
82
138
|
}
|
|
83
139
|
});
|
|
84
140
|
|
|
@@ -88,6 +144,7 @@
|
|
|
88
144
|
|
|
89
145
|
// Size styles
|
|
90
146
|
styles.push(`height: ${sizeConfig().height};`);
|
|
147
|
+
styles.push(`width: ${sizeConfig().width};`);
|
|
91
148
|
styles.push(`padding: ${sizeConfig().padding};`);
|
|
92
149
|
styles.push(`font-size: ${sizeConfig().fontSize};`);
|
|
93
150
|
styles.push(`border-radius: ${sizeConfig().borderRadius};`);
|
|
@@ -152,6 +209,38 @@
|
|
|
152
209
|
return classes.join(' ');
|
|
153
210
|
});
|
|
154
211
|
|
|
212
|
+
let showTooltip = $state(false);
|
|
213
|
+
let actualPosition = $state<'top' | 'bottom' | 'left' | 'right'>('right');
|
|
214
|
+
let buttonEl: HTMLButtonElement | null = $state(null);
|
|
215
|
+
|
|
216
|
+
function updateTooltipPosition() {
|
|
217
|
+
if (tooltipPosition !== 'auto') {
|
|
218
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
219
|
+
actualPosition = tooltipPosition as any;
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (!buttonEl) return;
|
|
224
|
+
|
|
225
|
+
const rect = buttonEl.getBoundingClientRect();
|
|
226
|
+
const viewportWidth = window.innerWidth;
|
|
227
|
+
// const viewportHeight = window.innerHeight;
|
|
228
|
+
const tooltipMargin = 12;
|
|
229
|
+
const estimatedWidth = 120; // heuristic
|
|
230
|
+
const estimatedHeight = 40; // heuristic
|
|
231
|
+
|
|
232
|
+
// Priority: Right -> Left -> Top -> Bottom
|
|
233
|
+
if (rect.right + estimatedWidth + tooltipMargin < viewportWidth) {
|
|
234
|
+
actualPosition = 'right';
|
|
235
|
+
} else if (rect.left - estimatedWidth - tooltipMargin > 0) {
|
|
236
|
+
actualPosition = 'left';
|
|
237
|
+
} else if (rect.top - estimatedHeight - tooltipMargin > 0) {
|
|
238
|
+
actualPosition = 'top';
|
|
239
|
+
} else {
|
|
240
|
+
actualPosition = 'bottom';
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
155
244
|
function handleClick() {
|
|
156
245
|
if (!disabled && !isLoading && onclick) {
|
|
157
246
|
onclick();
|
|
@@ -159,21 +248,33 @@
|
|
|
159
248
|
}
|
|
160
249
|
|
|
161
250
|
function handleMouseEnter() {
|
|
251
|
+
if (tooltip) {
|
|
252
|
+
updateTooltipPosition();
|
|
253
|
+
showTooltip = true;
|
|
254
|
+
}
|
|
162
255
|
if (!disabled && !isLoading && onmouseenter) {
|
|
163
256
|
onmouseenter();
|
|
164
257
|
}
|
|
165
258
|
}
|
|
259
|
+
|
|
260
|
+
function handleMouseLeave() {
|
|
261
|
+
showTooltip = false;
|
|
262
|
+
if (!disabled && !isLoading && onmouseleave) {
|
|
263
|
+
onmouseleave();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
166
266
|
</script>
|
|
167
267
|
|
|
168
268
|
{#if isShow}
|
|
169
269
|
<button
|
|
270
|
+
bind:this={buttonEl}
|
|
170
271
|
type="button"
|
|
171
272
|
class={buttonClasses()}
|
|
172
273
|
style={buttonStyles()}
|
|
173
274
|
disabled={disabled || isLoading}
|
|
174
275
|
onclick={handleClick}
|
|
175
276
|
onmouseenter={handleMouseEnter}
|
|
176
|
-
|
|
277
|
+
onmouseleave={handleMouseLeave}
|
|
177
278
|
{...props}
|
|
178
279
|
>
|
|
179
280
|
{#if isLoading}
|
|
@@ -194,5 +295,17 @@
|
|
|
194
295
|
{#if !isLoading && icon && iconPosition === 'right'}
|
|
195
296
|
<Icon name={icon} color={iconColor || 'currentColor'} width={16} height={16} />
|
|
196
297
|
{/if}
|
|
298
|
+
|
|
299
|
+
{#if tooltip && showTooltip}
|
|
300
|
+
<div class="btn-tooltip-container tooltip-{actualPosition}">
|
|
301
|
+
<div
|
|
302
|
+
class="btn-tooltip"
|
|
303
|
+
style={`--tooltip-bg-color: ${tooltipBgColor}; --tooltip-text-color: ${tooltipTextColor};`}
|
|
304
|
+
>
|
|
305
|
+
{tooltip}
|
|
306
|
+
<div class="tooltip-arrow"></div>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
{/if}
|
|
197
310
|
</button>
|
|
198
311
|
{/if}
|
|
@@ -3,7 +3,7 @@ import type { TIconName } from '../../icons/index.js';
|
|
|
3
3
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
4
4
|
interface Props extends Omit<HTMLButtonAttributes, 'type'> {
|
|
5
5
|
type?: 'solid' | 'outline';
|
|
6
|
-
size?: 48 | 40 | 32;
|
|
6
|
+
size?: 48 | 40 | 32 | 24 | 20 | 16;
|
|
7
7
|
backgroundColor?: string;
|
|
8
8
|
textColor?: string;
|
|
9
9
|
borderColor?: string;
|
|
@@ -16,10 +16,14 @@ interface Props extends Omit<HTMLButtonAttributes, 'type'> {
|
|
|
16
16
|
label?: string;
|
|
17
17
|
onclick?: () => void;
|
|
18
18
|
onmouseenter?: () => void;
|
|
19
|
+
onmouseleave?: () => void;
|
|
19
20
|
isLoading?: boolean;
|
|
20
21
|
isShow?: boolean;
|
|
21
22
|
disabled?: boolean;
|
|
22
23
|
tooltip?: string;
|
|
24
|
+
tooltipPosition?: 'top' | 'bottom' | 'left' | 'right' | 'auto';
|
|
25
|
+
tooltipBgColor?: string;
|
|
26
|
+
tooltipTextColor?: string;
|
|
23
27
|
class?: string;
|
|
24
28
|
style?: string;
|
|
25
29
|
}
|
|
@@ -92,3 +92,86 @@
|
|
|
92
92
|
display: inline-flex;
|
|
93
93
|
align-items: center;
|
|
94
94
|
}
|
|
95
|
+
|
|
96
|
+
/* Tooltip */
|
|
97
|
+
.btn-tooltip-container {
|
|
98
|
+
position: absolute;
|
|
99
|
+
z-index: 50;
|
|
100
|
+
pointer-events: none;
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
justify-content: center;
|
|
104
|
+
opacity: 0;
|
|
105
|
+
animation: tooltip-fade-in 0.2s forwards;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@keyframes tooltip-fade-in {
|
|
109
|
+
from {
|
|
110
|
+
opacity: 0;
|
|
111
|
+
}
|
|
112
|
+
to {
|
|
113
|
+
opacity: 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.btn-tooltip {
|
|
118
|
+
background-color: var(--tooltip-bg-color);
|
|
119
|
+
color: var(--tooltip-text-color);
|
|
120
|
+
padding: 8px 14px;
|
|
121
|
+
border-radius: 10px;
|
|
122
|
+
font-size: 13px;
|
|
123
|
+
font-weight: 500;
|
|
124
|
+
white-space: nowrap;
|
|
125
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
|
|
126
|
+
position: relative;
|
|
127
|
+
line-height: 1.2;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.tooltip-arrow {
|
|
131
|
+
position: absolute;
|
|
132
|
+
width: 8px;
|
|
133
|
+
height: 8px;
|
|
134
|
+
background-color: var(--tooltip-bg-color);
|
|
135
|
+
transform: rotate(45deg);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Positions */
|
|
139
|
+
.tooltip-top {
|
|
140
|
+
bottom: 100%;
|
|
141
|
+
left: 50%;
|
|
142
|
+
transform: translateX(-50%) translateY(-10px);
|
|
143
|
+
}
|
|
144
|
+
.tooltip-top .tooltip-arrow {
|
|
145
|
+
bottom: -4px;
|
|
146
|
+
left: calc(50% - 4px);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.tooltip-bottom {
|
|
150
|
+
top: 100%;
|
|
151
|
+
left: 50%;
|
|
152
|
+
transform: translateX(-50%) translateY(10px);
|
|
153
|
+
}
|
|
154
|
+
.tooltip-bottom .tooltip-arrow {
|
|
155
|
+
top: -4px;
|
|
156
|
+
left: calc(50% - 4px);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.tooltip-left {
|
|
160
|
+
right: 100%;
|
|
161
|
+
top: 50%;
|
|
162
|
+
transform: translateY(-50%) translateX(-10px);
|
|
163
|
+
}
|
|
164
|
+
.tooltip-left .tooltip-arrow {
|
|
165
|
+
right: -4px;
|
|
166
|
+
top: calc(50% - 4px);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.tooltip-right {
|
|
170
|
+
left: 100%;
|
|
171
|
+
top: 50%;
|
|
172
|
+
transform: translateY(-50%) translateX(10px);
|
|
173
|
+
}
|
|
174
|
+
.tooltip-right .tooltip-arrow {
|
|
175
|
+
left: -4px;
|
|
176
|
+
top: calc(50% - 4px);
|
|
177
|
+
}
|