mertani-web-toolkit 0.1.69 → 0.1.71
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/components/Button/Button.svelte +36 -78
- package/dist/components/Button/button.css +3 -80
- package/dist/components/Icon/Icon.svelte +66 -2
- package/dist/components/Tooltip/Tooltip.svelte +99 -0
- package/dist/components/Tooltip/Tooltip.svelte.d.ts +23 -0
- package/dist/components/Tooltip/tooltip.css +88 -0
- package/dist/icons/index.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +3 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import './button.css';
|
|
3
|
-
import { Icon } from '../../index.js';
|
|
3
|
+
import { Icon, Tooltip } from '../../index.js';
|
|
4
4
|
import type { TIconName } from '../../icons/index.js';
|
|
5
5
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
6
6
|
|
|
@@ -209,38 +209,6 @@
|
|
|
209
209
|
return classes.join(' ');
|
|
210
210
|
});
|
|
211
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
|
-
|
|
244
212
|
function handleClick() {
|
|
245
213
|
if (!disabled && !isLoading && onclick) {
|
|
246
214
|
onclick();
|
|
@@ -248,17 +216,12 @@
|
|
|
248
216
|
}
|
|
249
217
|
|
|
250
218
|
function handleMouseEnter() {
|
|
251
|
-
if (tooltip) {
|
|
252
|
-
updateTooltipPosition();
|
|
253
|
-
showTooltip = true;
|
|
254
|
-
}
|
|
255
219
|
if (!disabled && !isLoading && onmouseenter) {
|
|
256
220
|
onmouseenter();
|
|
257
221
|
}
|
|
258
222
|
}
|
|
259
223
|
|
|
260
224
|
function handleMouseLeave() {
|
|
261
|
-
showTooltip = false;
|
|
262
225
|
if (!disabled && !isLoading && onmouseleave) {
|
|
263
226
|
onmouseleave();
|
|
264
227
|
}
|
|
@@ -266,46 +229,41 @@
|
|
|
266
229
|
</script>
|
|
267
230
|
|
|
268
231
|
{#if isShow}
|
|
269
|
-
<
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
232
|
+
<Tooltip
|
|
233
|
+
text={tooltip}
|
|
234
|
+
position={tooltipPosition}
|
|
235
|
+
bgColor={tooltipBgColor}
|
|
236
|
+
textColor={tooltipTextColor}
|
|
274
237
|
disabled={disabled || isLoading}
|
|
275
|
-
onclick={handleClick}
|
|
276
|
-
onmouseenter={handleMouseEnter}
|
|
277
|
-
onmouseleave={handleMouseLeave}
|
|
278
|
-
{...props}
|
|
279
238
|
>
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
</button>
|
|
239
|
+
<button
|
|
240
|
+
type="button"
|
|
241
|
+
class={buttonClasses()}
|
|
242
|
+
style={buttonStyles()}
|
|
243
|
+
disabled={disabled || isLoading}
|
|
244
|
+
onclick={handleClick}
|
|
245
|
+
onmouseenter={handleMouseEnter}
|
|
246
|
+
onmouseleave={handleMouseLeave}
|
|
247
|
+
{...props}
|
|
248
|
+
>
|
|
249
|
+
{#if isLoading}
|
|
250
|
+
<span
|
|
251
|
+
class="btn-loader"
|
|
252
|
+
style={loaderColor
|
|
253
|
+
? `border-top-color: ${loaderColor}; border-right-color: ${loaderColor};`
|
|
254
|
+
: ''}
|
|
255
|
+
></span>
|
|
256
|
+
{:else if icon && iconPosition === 'left'}
|
|
257
|
+
<Icon name={icon} color={iconColor || 'currentColor'} width={16} height={16} />
|
|
258
|
+
{/if}
|
|
259
|
+
|
|
260
|
+
{#if label}
|
|
261
|
+
<span class="btn-label">{label}</span>
|
|
262
|
+
{/if}
|
|
263
|
+
|
|
264
|
+
{#if !isLoading && icon && iconPosition === 'right'}
|
|
265
|
+
<Icon name={icon} color={iconColor || 'currentColor'} width={16} height={16} />
|
|
266
|
+
{/if}
|
|
267
|
+
</button>
|
|
268
|
+
</Tooltip>
|
|
311
269
|
{/if}
|
|
@@ -93,85 +93,8 @@
|
|
|
93
93
|
align-items: center;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
/*
|
|
97
|
-
.btn-
|
|
98
|
-
|
|
99
|
-
z-index: 50;
|
|
100
|
-
pointer-events: none;
|
|
101
|
-
display: flex;
|
|
96
|
+
/* Button Label */
|
|
97
|
+
.btn-label {
|
|
98
|
+
display: inline-flex;
|
|
102
99
|
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
100
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { iconMap } from '../../icons/index.js';
|
|
3
3
|
import type { TIconName } from '../../icons/index.js';
|
|
4
|
+
import * as lucideIcons from 'lucide-svelte';
|
|
5
|
+
import IconifyIcon from '@iconify/svelte';
|
|
4
6
|
|
|
5
7
|
interface IconProps {
|
|
6
8
|
name: TIconName;
|
|
@@ -14,7 +16,36 @@
|
|
|
14
16
|
|
|
15
17
|
const { name, width, height, color, style, onclick, opacity }: IconProps = $props();
|
|
16
18
|
|
|
17
|
-
const IconComponent = $derived(iconMap[name]);
|
|
19
|
+
const IconComponent = $derived(iconMap[name as keyof typeof iconMap]);
|
|
20
|
+
|
|
21
|
+
// cek apakah ada di lucide
|
|
22
|
+
// lucide pakai PascalCase: "arrow-right" → "ArrowRight"
|
|
23
|
+
const lucideName = $derived(
|
|
24
|
+
name
|
|
25
|
+
.split('-')
|
|
26
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
27
|
+
.join('')
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
+
const LucideIcon = $derived((lucideIcons as any)[lucideName] ?? null);
|
|
32
|
+
|
|
33
|
+
// heuristic: jika ada colon ":" biasanya itu iconify set
|
|
34
|
+
const isIconify = $derived(name.includes(':'));
|
|
35
|
+
|
|
36
|
+
const sizeValue = $derived(() => {
|
|
37
|
+
if (typeof width === 'number') return width;
|
|
38
|
+
if (typeof width === 'string') {
|
|
39
|
+
const parsed = parseInt(width);
|
|
40
|
+
if (!isNaN(parsed)) return parsed;
|
|
41
|
+
}
|
|
42
|
+
if (typeof height === 'number') return height;
|
|
43
|
+
if (typeof height === 'string') {
|
|
44
|
+
const parsed = parseInt(height);
|
|
45
|
+
if (!isNaN(parsed)) return parsed;
|
|
46
|
+
}
|
|
47
|
+
return 24;
|
|
48
|
+
});
|
|
18
49
|
|
|
19
50
|
const iconWidth = $derived(
|
|
20
51
|
width !== undefined ? (typeof width === 'number' ? `${width}px` : width) : 'auto'
|
|
@@ -56,7 +87,7 @@
|
|
|
56
87
|
</script>
|
|
57
88
|
|
|
58
89
|
{#if IconComponent}
|
|
59
|
-
{@const Component = IconComponent
|
|
90
|
+
{@const Component = IconComponent}
|
|
60
91
|
<div
|
|
61
92
|
class="icon-wrapper"
|
|
62
93
|
class:icon-clickable={onclick !== undefined}
|
|
@@ -74,6 +105,39 @@
|
|
|
74
105
|
<Component />
|
|
75
106
|
</div>
|
|
76
107
|
</div>
|
|
108
|
+
{:else if LucideIcon}
|
|
109
|
+
<div
|
|
110
|
+
class="icon-wrapper"
|
|
111
|
+
class:icon-clickable={onclick !== undefined}
|
|
112
|
+
style={combinedStyles()}
|
|
113
|
+
onclick={onclick ? handleClick : undefined}
|
|
114
|
+
role={onclick ? 'button' : undefined}
|
|
115
|
+
onkeydown={(e) => {
|
|
116
|
+
if (onclick && (e.key === 'Enter' || e.key === ' ')) {
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
handleClick();
|
|
119
|
+
}
|
|
120
|
+
}}
|
|
121
|
+
>
|
|
122
|
+
<!-- svelte-ignore svelte_component_deprecated -->
|
|
123
|
+
<svelte:component this={LucideIcon} size={sizeValue()} color={iconColor} />
|
|
124
|
+
</div>
|
|
125
|
+
{:else if isIconify}
|
|
126
|
+
<div
|
|
127
|
+
class="icon-wrapper"
|
|
128
|
+
class:icon-clickable={onclick !== undefined}
|
|
129
|
+
style={combinedStyles()}
|
|
130
|
+
onclick={onclick ? handleClick : undefined}
|
|
131
|
+
role={onclick ? 'button' : undefined}
|
|
132
|
+
onkeydown={(e) => {
|
|
133
|
+
if (onclick && (e.key === 'Enter' || e.key === ' ')) {
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
handleClick();
|
|
136
|
+
}
|
|
137
|
+
}}
|
|
138
|
+
>
|
|
139
|
+
<IconifyIcon icon={name} width={sizeValue()} height={sizeValue()} style="color: {iconColor}" />
|
|
140
|
+
</div>
|
|
77
141
|
{:else}
|
|
78
142
|
<span class="icon-error">Icon "{name}" tidak ditemukan</span>
|
|
79
143
|
{/if}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import './tooltip.css';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
/** Teks yang akan ditampilkan dalam tooltip */
|
|
7
|
+
text?: string;
|
|
8
|
+
/** Posisi tooltip: top, bottom, left, right, atau auto (default: auto) */
|
|
9
|
+
position?: 'top' | 'bottom' | 'left' | 'right' | 'auto';
|
|
10
|
+
/** Warna background kustom untuk tooltip */
|
|
11
|
+
bgColor?: string;
|
|
12
|
+
/** Warna teks kustom untuk tooltip */
|
|
13
|
+
textColor?: string;
|
|
14
|
+
/** Konten yang akan diberikan tooltip saat di-hover */
|
|
15
|
+
children?: Snippet;
|
|
16
|
+
/** Jika true, tooltip tidak akan muncul */
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
/** Custom CSS class untuk wrapper */
|
|
19
|
+
class?: string;
|
|
20
|
+
/** Custom inline style untuk wrapper */
|
|
21
|
+
style?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
text = '',
|
|
26
|
+
position = 'auto',
|
|
27
|
+
bgColor = 'var(--color-bg-inverse)',
|
|
28
|
+
textColor = 'var(--color-text-inverse)',
|
|
29
|
+
children,
|
|
30
|
+
disabled = false,
|
|
31
|
+
class: className = '',
|
|
32
|
+
style: customStyle = ''
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
|
|
35
|
+
let showTooltip = $state(false);
|
|
36
|
+
let actualPosition = $state<'top' | 'bottom' | 'left' | 'right'>('right');
|
|
37
|
+
let wrapperEl: HTMLDivElement | null = $state(null);
|
|
38
|
+
|
|
39
|
+
function updateTooltipPosition() {
|
|
40
|
+
if (position !== 'auto') {
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
actualPosition = position as any;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!wrapperEl) return;
|
|
47
|
+
|
|
48
|
+
const rect = wrapperEl.getBoundingClientRect();
|
|
49
|
+
const viewportWidth = window.innerWidth;
|
|
50
|
+
const tooltipMargin = 12;
|
|
51
|
+
const estimatedWidth = 120; // heuristic
|
|
52
|
+
const estimatedHeight = 40; // heuristic
|
|
53
|
+
|
|
54
|
+
// Priority: Right -> Left -> Top -> Bottom
|
|
55
|
+
if (rect.right + estimatedWidth + tooltipMargin < viewportWidth) {
|
|
56
|
+
actualPosition = 'right';
|
|
57
|
+
} else if (rect.left - estimatedWidth - tooltipMargin > 0) {
|
|
58
|
+
actualPosition = 'left';
|
|
59
|
+
} else if (rect.top - estimatedHeight - tooltipMargin > 0) {
|
|
60
|
+
actualPosition = 'top';
|
|
61
|
+
} else {
|
|
62
|
+
actualPosition = 'bottom';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function handleMouseEnter() {
|
|
67
|
+
if (!disabled && text) {
|
|
68
|
+
updateTooltipPosition();
|
|
69
|
+
showTooltip = true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function handleMouseLeave() {
|
|
74
|
+
showTooltip = false;
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<div
|
|
79
|
+
bind:this={wrapperEl}
|
|
80
|
+
class="tooltip-wrapper {className}"
|
|
81
|
+
style={customStyle}
|
|
82
|
+
onmouseenter={handleMouseEnter}
|
|
83
|
+
onmouseleave={handleMouseLeave}
|
|
84
|
+
role="presentation"
|
|
85
|
+
>
|
|
86
|
+
{@render children?.()}
|
|
87
|
+
|
|
88
|
+
{#if text && showTooltip}
|
|
89
|
+
<div class="tooltip-container tooltip-{actualPosition}">
|
|
90
|
+
<div
|
|
91
|
+
class="tooltip-content"
|
|
92
|
+
style={`--tooltip-bg-color: ${bgColor}; --tooltip-text-color: ${textColor};`}
|
|
93
|
+
>
|
|
94
|
+
{text}
|
|
95
|
+
<div class="tooltip-arrow"></div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
{/if}
|
|
99
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import './tooltip.css';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
interface Props {
|
|
4
|
+
/** Teks yang akan ditampilkan dalam tooltip */
|
|
5
|
+
text?: string;
|
|
6
|
+
/** Posisi tooltip: top, bottom, left, right, atau auto (default: auto) */
|
|
7
|
+
position?: 'top' | 'bottom' | 'left' | 'right' | 'auto';
|
|
8
|
+
/** Warna background kustom untuk tooltip */
|
|
9
|
+
bgColor?: string;
|
|
10
|
+
/** Warna teks kustom untuk tooltip */
|
|
11
|
+
textColor?: string;
|
|
12
|
+
/** Konten yang akan diberikan tooltip saat di-hover */
|
|
13
|
+
children?: Snippet;
|
|
14
|
+
/** Jika true, tooltip tidak akan muncul */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
/** Custom CSS class untuk wrapper */
|
|
17
|
+
class?: string;
|
|
18
|
+
/** Custom inline style untuk wrapper */
|
|
19
|
+
style?: string;
|
|
20
|
+
}
|
|
21
|
+
declare const Tooltip: import("svelte").Component<Props, {}, "">;
|
|
22
|
+
type Tooltip = ReturnType<typeof Tooltip>;
|
|
23
|
+
export default Tooltip;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* Tooltip Container */
|
|
2
|
+
.tooltip-container {
|
|
3
|
+
position: absolute;
|
|
4
|
+
z-index: 50;
|
|
5
|
+
pointer-events: none;
|
|
6
|
+
display: flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
opacity: 0;
|
|
10
|
+
animation: tooltip-fade-in 0.2s forwards;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@keyframes tooltip-fade-in {
|
|
14
|
+
from {
|
|
15
|
+
opacity: 0;
|
|
16
|
+
}
|
|
17
|
+
to {
|
|
18
|
+
opacity: 1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.tooltip-content {
|
|
23
|
+
background-color: var(--tooltip-bg-color, var(--color-bg-inverse, #111111));
|
|
24
|
+
color: var(--tooltip-text-color, var(--color-text-inverse, #ffffff));
|
|
25
|
+
padding: 8px 14px;
|
|
26
|
+
border-radius: 10px;
|
|
27
|
+
font-size: 13px;
|
|
28
|
+
font-weight: 500;
|
|
29
|
+
white-space: nowrap;
|
|
30
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
|
|
31
|
+
position: relative;
|
|
32
|
+
line-height: 1.2;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.tooltip-arrow {
|
|
36
|
+
position: absolute;
|
|
37
|
+
width: 8px;
|
|
38
|
+
height: 8px;
|
|
39
|
+
background-color: var(--tooltip-bg-color, var(--color-bg-inverse, #111111));
|
|
40
|
+
transform: rotate(45deg);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Positions */
|
|
44
|
+
.tooltip-top {
|
|
45
|
+
bottom: 100%;
|
|
46
|
+
left: 50%;
|
|
47
|
+
transform: translateX(-50%) translateY(-10px);
|
|
48
|
+
}
|
|
49
|
+
.tooltip-top .tooltip-arrow {
|
|
50
|
+
bottom: -4px;
|
|
51
|
+
left: calc(50% - 4px);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.tooltip-bottom {
|
|
55
|
+
top: 100%;
|
|
56
|
+
left: 50%;
|
|
57
|
+
transform: translateX(-50%) translateY(10px);
|
|
58
|
+
}
|
|
59
|
+
.tooltip-bottom .tooltip-arrow {
|
|
60
|
+
top: -4px;
|
|
61
|
+
left: calc(50% - 4px);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.tooltip-left {
|
|
65
|
+
right: 100%;
|
|
66
|
+
top: 50%;
|
|
67
|
+
transform: translateY(-50%) translateX(-10px);
|
|
68
|
+
}
|
|
69
|
+
.tooltip-left .tooltip-arrow {
|
|
70
|
+
right: -4px;
|
|
71
|
+
top: calc(50% - 4px);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.tooltip-right {
|
|
75
|
+
left: 100%;
|
|
76
|
+
top: 50%;
|
|
77
|
+
transform: translateY(-50%) translateX(10px);
|
|
78
|
+
}
|
|
79
|
+
.tooltip-right .tooltip-arrow {
|
|
80
|
+
left: -4px;
|
|
81
|
+
top: calc(50% - 4px);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Wrapper */
|
|
85
|
+
.tooltip-wrapper {
|
|
86
|
+
position: relative;
|
|
87
|
+
display: inline-flex;
|
|
88
|
+
}
|
package/dist/icons/index.js
CHANGED
|
@@ -259,8 +259,8 @@ export const iconMap = {
|
|
|
259
259
|
berawan: Berawan,
|
|
260
260
|
'berawan-tebal': BerawanTebal,
|
|
261
261
|
'udara-kabut': UdaraKabut,
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
kabut: Kabut,
|
|
263
|
+
asap: Asap,
|
|
264
264
|
'hujan-ringan': HujanRingan,
|
|
265
265
|
'hujan-sedang': HujanSedang,
|
|
266
266
|
'hujan-lebat': HujanLebat,
|
package/dist/index.d.ts
CHANGED
|
@@ -26,4 +26,5 @@ export { default as MapMarkerGroup } from './components/map/MapMarkerGroup.svelt
|
|
|
26
26
|
export { default as MapGeoJSON } from './components/map/MapGeoJSON.svelte';
|
|
27
27
|
export { default as MapTopoJSON } from './components/map/MapTopoJSON.svelte';
|
|
28
28
|
export { default as MapVelocity } from './components/map/MapVelocity.svelte';
|
|
29
|
+
export { default as Tooltip } from './components/Tooltip/Tooltip.svelte';
|
|
29
30
|
export type { Column, DeviceStatus, TableAction } from './components/Table/types.js';
|
package/dist/index.js
CHANGED
|
@@ -26,3 +26,4 @@ export { default as MapMarkerGroup } from './components/map/MapMarkerGroup.svelt
|
|
|
26
26
|
export { default as MapGeoJSON } from './components/map/MapGeoJSON.svelte';
|
|
27
27
|
export { default as MapTopoJSON } from './components/map/MapTopoJSON.svelte';
|
|
28
28
|
export { default as MapVelocity } from './components/map/MapVelocity.svelte';
|
|
29
|
+
export { default as Tooltip } from './components/Tooltip/Tooltip.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mertani-web-toolkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.71",
|
|
4
4
|
"homepage": "https://storybook.mertani.com/",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
@@ -79,8 +79,10 @@
|
|
|
79
79
|
"svelte"
|
|
80
80
|
],
|
|
81
81
|
"dependencies": {
|
|
82
|
+
"@iconify/svelte": "^5.2.1",
|
|
82
83
|
"leaflet.markercluster": "^1.5.3",
|
|
83
84
|
"leaflet-velocity": "^1.5.0",
|
|
85
|
+
"lucide-svelte": "^1.0.1",
|
|
84
86
|
"tailwind-merge": "^3.4.0",
|
|
85
87
|
"topojson-client": "^3.1.0"
|
|
86
88
|
}
|