mertani-web-toolkit 0.1.66 → 0.1.67
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,14 @@
|
|
|
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';
|
|
34
36
|
|
|
35
37
|
// Any
|
|
36
38
|
class?: string;
|
|
@@ -53,18 +55,20 @@
|
|
|
53
55
|
|
|
54
56
|
// ===Properties===
|
|
55
57
|
// Data
|
|
56
|
-
label = '
|
|
58
|
+
label = '',
|
|
57
59
|
|
|
58
60
|
// Additional Actions
|
|
59
61
|
isLoading = false,
|
|
60
62
|
isShow = true,
|
|
61
63
|
disabled = false,
|
|
62
64
|
tooltip = '',
|
|
65
|
+
tooltipPosition = 'auto',
|
|
63
66
|
|
|
64
67
|
class: className = '',
|
|
65
68
|
style: customStyle = '',
|
|
66
69
|
onclick,
|
|
67
70
|
onmouseenter,
|
|
71
|
+
onmouseleave,
|
|
68
72
|
...props
|
|
69
73
|
}: Props = $props();
|
|
70
74
|
|
|
@@ -72,13 +76,61 @@
|
|
|
72
76
|
const sizeConfig = $derived(() => {
|
|
73
77
|
switch (size) {
|
|
74
78
|
case 48:
|
|
75
|
-
return {
|
|
79
|
+
return {
|
|
80
|
+
height: '48px',
|
|
81
|
+
width: label ? 'auto' : '48px',
|
|
82
|
+
padding: label ? '10px 24px' : '10px',
|
|
83
|
+
fontSize: '18px',
|
|
84
|
+
borderRadius: '8px'
|
|
85
|
+
};
|
|
76
86
|
case 40:
|
|
77
|
-
return {
|
|
87
|
+
return {
|
|
88
|
+
height: '40px',
|
|
89
|
+
width: label ? 'auto' : '40px',
|
|
90
|
+
padding: label ? '8px 16px' : '8px',
|
|
91
|
+
fontSize: '16px',
|
|
92
|
+
borderRadius: '8px'
|
|
93
|
+
};
|
|
78
94
|
case 32:
|
|
79
|
-
return {
|
|
95
|
+
return {
|
|
96
|
+
height: '32px',
|
|
97
|
+
width: label ? 'auto' : '32px',
|
|
98
|
+
padding: label ? '6px 12px' : '6px',
|
|
99
|
+
fontSize: '14px',
|
|
100
|
+
borderRadius: '6px'
|
|
101
|
+
};
|
|
102
|
+
case 24:
|
|
103
|
+
return {
|
|
104
|
+
height: '24px',
|
|
105
|
+
width: label ? 'auto' : '24px',
|
|
106
|
+
padding: label ? '4px 8px' : '4px',
|
|
107
|
+
fontSize: '12px',
|
|
108
|
+
borderRadius: '4px'
|
|
109
|
+
};
|
|
110
|
+
case 20:
|
|
111
|
+
return {
|
|
112
|
+
height: '20px',
|
|
113
|
+
width: label ? 'auto' : '20px',
|
|
114
|
+
padding: label ? '2px 6px' : '2px',
|
|
115
|
+
fontSize: '10px',
|
|
116
|
+
borderRadius: '4px'
|
|
117
|
+
};
|
|
118
|
+
case 16:
|
|
119
|
+
return {
|
|
120
|
+
height: '16px',
|
|
121
|
+
width: label ? 'auto' : '16px',
|
|
122
|
+
padding: label ? '0px 4px' : '0px',
|
|
123
|
+
fontSize: '10px',
|
|
124
|
+
borderRadius: '4px'
|
|
125
|
+
};
|
|
80
126
|
default:
|
|
81
|
-
return {
|
|
127
|
+
return {
|
|
128
|
+
height: '40px',
|
|
129
|
+
width: label ? 'auto' : '40px',
|
|
130
|
+
padding: label ? '8px 16px' : '8px',
|
|
131
|
+
fontSize: '16px',
|
|
132
|
+
borderRadius: '8px'
|
|
133
|
+
};
|
|
82
134
|
}
|
|
83
135
|
});
|
|
84
136
|
|
|
@@ -88,6 +140,7 @@
|
|
|
88
140
|
|
|
89
141
|
// Size styles
|
|
90
142
|
styles.push(`height: ${sizeConfig().height};`);
|
|
143
|
+
styles.push(`width: ${sizeConfig().width};`);
|
|
91
144
|
styles.push(`padding: ${sizeConfig().padding};`);
|
|
92
145
|
styles.push(`font-size: ${sizeConfig().fontSize};`);
|
|
93
146
|
styles.push(`border-radius: ${sizeConfig().borderRadius};`);
|
|
@@ -152,6 +205,38 @@
|
|
|
152
205
|
return classes.join(' ');
|
|
153
206
|
});
|
|
154
207
|
|
|
208
|
+
let showTooltip = $state(false);
|
|
209
|
+
let actualPosition = $state<'top' | 'bottom' | 'left' | 'right'>('right');
|
|
210
|
+
let buttonEl: HTMLButtonElement | null = $state(null);
|
|
211
|
+
|
|
212
|
+
function updateTooltipPosition() {
|
|
213
|
+
if (tooltipPosition !== 'auto') {
|
|
214
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
215
|
+
actualPosition = tooltipPosition as any;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!buttonEl) return;
|
|
220
|
+
|
|
221
|
+
const rect = buttonEl.getBoundingClientRect();
|
|
222
|
+
const viewportWidth = window.innerWidth;
|
|
223
|
+
// const viewportHeight = window.innerHeight;
|
|
224
|
+
const tooltipMargin = 12;
|
|
225
|
+
const estimatedWidth = 120; // heuristic
|
|
226
|
+
const estimatedHeight = 40; // heuristic
|
|
227
|
+
|
|
228
|
+
// Priority: Right -> Left -> Top -> Bottom
|
|
229
|
+
if (rect.right + estimatedWidth + tooltipMargin < viewportWidth) {
|
|
230
|
+
actualPosition = 'right';
|
|
231
|
+
} else if (rect.left - estimatedWidth - tooltipMargin > 0) {
|
|
232
|
+
actualPosition = 'left';
|
|
233
|
+
} else if (rect.top - estimatedHeight - tooltipMargin > 0) {
|
|
234
|
+
actualPosition = 'top';
|
|
235
|
+
} else {
|
|
236
|
+
actualPosition = 'bottom';
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
155
240
|
function handleClick() {
|
|
156
241
|
if (!disabled && !isLoading && onclick) {
|
|
157
242
|
onclick();
|
|
@@ -159,21 +244,33 @@
|
|
|
159
244
|
}
|
|
160
245
|
|
|
161
246
|
function handleMouseEnter() {
|
|
247
|
+
if (tooltip) {
|
|
248
|
+
updateTooltipPosition();
|
|
249
|
+
showTooltip = true;
|
|
250
|
+
}
|
|
162
251
|
if (!disabled && !isLoading && onmouseenter) {
|
|
163
252
|
onmouseenter();
|
|
164
253
|
}
|
|
165
254
|
}
|
|
255
|
+
|
|
256
|
+
function handleMouseLeave() {
|
|
257
|
+
showTooltip = false;
|
|
258
|
+
if (!disabled && !isLoading && onmouseleave) {
|
|
259
|
+
onmouseleave();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
166
262
|
</script>
|
|
167
263
|
|
|
168
264
|
{#if isShow}
|
|
169
265
|
<button
|
|
266
|
+
bind:this={buttonEl}
|
|
170
267
|
type="button"
|
|
171
268
|
class={buttonClasses()}
|
|
172
269
|
style={buttonStyles()}
|
|
173
270
|
disabled={disabled || isLoading}
|
|
174
271
|
onclick={handleClick}
|
|
175
272
|
onmouseenter={handleMouseEnter}
|
|
176
|
-
|
|
273
|
+
onmouseleave={handleMouseLeave}
|
|
177
274
|
{...props}
|
|
178
275
|
>
|
|
179
276
|
{#if isLoading}
|
|
@@ -194,5 +291,14 @@
|
|
|
194
291
|
{#if !isLoading && icon && iconPosition === 'right'}
|
|
195
292
|
<Icon name={icon} color={iconColor || 'currentColor'} width={16} height={16} />
|
|
196
293
|
{/if}
|
|
294
|
+
|
|
295
|
+
{#if tooltip && showTooltip}
|
|
296
|
+
<div class="btn-tooltip-container tooltip-{actualPosition}">
|
|
297
|
+
<div class="btn-tooltip">
|
|
298
|
+
{tooltip}
|
|
299
|
+
<div class="tooltip-arrow"></div>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
{/if}
|
|
197
303
|
</button>
|
|
198
304
|
{/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,12 @@ 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';
|
|
23
25
|
class?: string;
|
|
24
26
|
style?: string;
|
|
25
27
|
}
|
|
@@ -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(--color-bg-inverse);
|
|
119
|
+
color: var(--color-text-inverse);
|
|
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(--color-bg-inverse);
|
|
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
|
+
}
|