grav-svelte 0.0.97 → 0.0.98
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.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ButtonConfig } from "./interfaces.js";
|
|
3
3
|
import Tooltip from "./Tooltip.svelte";
|
|
4
|
+
import { onMount, afterUpdate } from "svelte";
|
|
4
5
|
|
|
5
6
|
export let id = 1;
|
|
6
7
|
export let buttonsConfig: ButtonConfig[];
|
|
@@ -8,14 +9,61 @@
|
|
|
8
9
|
export let row: any = undefined;
|
|
9
10
|
|
|
10
11
|
$: visibleButtons = buttonsConfig.filter((btn) => btn.show ?? true);
|
|
12
|
+
|
|
13
|
+
function handleClick(event: MouseEvent, button: ButtonConfig) {
|
|
14
|
+
event.stopPropagation();
|
|
15
|
+
button.action(id, row);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Prevenir que Font Awesome procese iconos múltiples veces
|
|
19
|
+
function preventIconDuplication(element: HTMLElement) {
|
|
20
|
+
if (!element) return;
|
|
21
|
+
|
|
22
|
+
const buttons = element.querySelectorAll('button');
|
|
23
|
+
buttons.forEach((button) => {
|
|
24
|
+
const icons = button.querySelectorAll('i[class*="fa-"]');
|
|
25
|
+
// Si hay más de un icono, eliminar los duplicados (mantener solo el primero)
|
|
26
|
+
if (icons.length > 1) {
|
|
27
|
+
for (let i = 1; i < icons.length; i++) {
|
|
28
|
+
icons[i].remove();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Marcar como procesado para evitar que Font Awesome lo procese de nuevo
|
|
32
|
+
icons.forEach((icon) => {
|
|
33
|
+
if (!icon.hasAttribute('data-fa-processed')) {
|
|
34
|
+
icon.setAttribute('data-fa-processed', 'true');
|
|
35
|
+
}
|
|
36
|
+
// Prevenir que Font Awesome convierta a SVG si ya es SVG
|
|
37
|
+
const svg = icon.querySelector('svg');
|
|
38
|
+
if (svg && icon.parentElement) {
|
|
39
|
+
// Si ya hay un SVG, eliminar el icono original
|
|
40
|
+
icon.style.display = 'none';
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let buttonGroupElement: HTMLDivElement;
|
|
47
|
+
|
|
48
|
+
onMount(() => {
|
|
49
|
+
if (buttonGroupElement) {
|
|
50
|
+
preventIconDuplication(buttonGroupElement);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
afterUpdate(() => {
|
|
55
|
+
if (buttonGroupElement) {
|
|
56
|
+
preventIconDuplication(buttonGroupElement);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
11
59
|
</script>
|
|
12
60
|
|
|
13
|
-
<div class="button-group" role="group">
|
|
14
|
-
{#each visibleButtons as button, i}
|
|
61
|
+
<div class="button-group" role="group" bind:this={buttonGroupElement}>
|
|
62
|
+
{#each visibleButtons as button, i (button.icon + id + i)}
|
|
15
63
|
<Tooltip text={button.tooltip}>
|
|
16
64
|
<button
|
|
17
65
|
aria-label={button.tooltip}
|
|
18
|
-
on:click={() =>
|
|
66
|
+
on:click={(e) => handleClick(e, button)}
|
|
19
67
|
type="button"
|
|
20
68
|
class="action-buttons-group {visibleButtons.length === 1
|
|
21
69
|
? 'rounded-left rounded-right'
|
|
@@ -25,7 +73,7 @@
|
|
|
25
73
|
? 'rounded-right'
|
|
26
74
|
: ''} {button.color}"
|
|
27
75
|
>
|
|
28
|
-
<i class={button.icon}> </i>
|
|
76
|
+
<i class={button.icon} data-fa-processed="true" data-fa-i2svg-processed="true"> </i>
|
|
29
77
|
</button>
|
|
30
78
|
</Tooltip>
|
|
31
79
|
{/each}
|
package/dist/CRUD/Tooltip.svelte
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
let showTooltip = false;
|
|
5
5
|
export let text: string;
|
|
6
|
+
|
|
7
|
+
function handleMouseEnter(event: MouseEvent) {
|
|
8
|
+
event.stopPropagation();
|
|
9
|
+
showTooltip = true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function handleMouseLeave(event: MouseEvent) {
|
|
13
|
+
event.stopPropagation();
|
|
14
|
+
showTooltip = false;
|
|
15
|
+
}
|
|
6
16
|
</script>
|
|
7
17
|
|
|
8
18
|
<div class="tooltip-container">
|
|
@@ -12,8 +22,8 @@
|
|
|
12
22
|
</div>
|
|
13
23
|
{/if}
|
|
14
24
|
<div
|
|
15
|
-
on:mouseenter={
|
|
16
|
-
on:mouseleave={
|
|
25
|
+
on:mouseenter={handleMouseEnter}
|
|
26
|
+
on:mouseleave={handleMouseLeave}
|
|
17
27
|
role="button"
|
|
18
28
|
tabindex="0"
|
|
19
29
|
>
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
$: alignStyle = header.align === 'left' ? 'margin-right: auto;' :
|
|
9
9
|
header.align === 'right' ? 'margin-left: auto;' : '';
|
|
10
|
+
|
|
11
|
+
function handleClick(event: MouseEvent) {
|
|
12
|
+
event.stopPropagation();
|
|
13
|
+
if (header.onButtonClick) {
|
|
14
|
+
header.onButtonClick(item[idField], item);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
10
17
|
</script>
|
|
11
18
|
|
|
12
19
|
<div style="display: inline-flex; {alignStyle}">
|
|
@@ -14,15 +21,11 @@
|
|
|
14
21
|
type="button"
|
|
15
22
|
class="dynamic-button"
|
|
16
23
|
style="{header.colorField && item[header.colorField] ? `background-color: ${item[header.colorField]}; color: white;` : ''} {header.styleField ? (item[header.styleField] ?? '') : ''}"
|
|
17
|
-
on:click={
|
|
18
|
-
if (header.onButtonClick) {
|
|
19
|
-
header.onButtonClick(item[idField], item);
|
|
20
|
-
}
|
|
21
|
-
}}
|
|
24
|
+
on:click={handleClick}
|
|
22
25
|
>
|
|
23
26
|
{#if header.iconField && item[header.iconField]}
|
|
24
27
|
{#if !header.iconPosition || header.iconPosition === "left"}
|
|
25
|
-
<i class="{item[header.iconField]} dynamic-button-icon-left"></i>
|
|
28
|
+
<i class="{item[header.iconField]} dynamic-button-icon-left" data-fa-processed="true" data-fa-i2svg-processed="true"></i>
|
|
26
29
|
{/if}
|
|
27
30
|
{/if}
|
|
28
31
|
{#if header.textField && item[header.textField]}
|
|
@@ -30,7 +33,7 @@
|
|
|
30
33
|
{/if}
|
|
31
34
|
{#if header.iconField && item[header.iconField]}
|
|
32
35
|
{#if header.iconPosition === "right"}
|
|
33
|
-
<i class="{item[header.iconField]} dynamic-button-icon-right"></i>
|
|
36
|
+
<i class="{item[header.iconField]} dynamic-button-icon-right" data-fa-processed="true" data-fa-i2svg-processed="true"></i>
|
|
34
37
|
{/if}
|
|
35
38
|
{/if}
|
|
36
39
|
</button>
|