@r2digisolutions/ui 0.24.5 → 0.24.7
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.
|
@@ -124,23 +124,19 @@
|
|
|
124
124
|
) {
|
|
125
125
|
e.preventDefault();
|
|
126
126
|
const columnIndex = columnId ? manager.state.visibleColumns.indexOf(columnId) : null;
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
setTimeout(() => {
|
|
131
|
-
rightMenu = { open: true, x: e.clientX, y: e.clientY };
|
|
132
|
-
}, 0);
|
|
133
|
-
} else {
|
|
127
|
+
// Reset menu state and set new coordinates
|
|
128
|
+
rightMenu = { open: false, x: 0, y: 0 };
|
|
129
|
+
tick().then(() => {
|
|
134
130
|
rightMenu = { open: true, x: e.clientX, y: e.clientY };
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
131
|
+
rightClickContext = {
|
|
132
|
+
row,
|
|
133
|
+
rowIndex,
|
|
134
|
+
columnId,
|
|
135
|
+
columnIndex,
|
|
136
|
+
event: e,
|
|
137
|
+
column: columnId ? manager.getColumn(columnId) : null
|
|
138
|
+
} as TDataTableCellContext<T>;
|
|
139
|
+
});
|
|
144
140
|
}
|
|
145
141
|
|
|
146
142
|
function selectedRows(): T[] {
|
|
@@ -148,7 +144,6 @@
|
|
|
148
144
|
return manager.state.items.filter((r) => ids.has(rowId(r)));
|
|
149
145
|
}
|
|
150
146
|
|
|
151
|
-
// Tracks
|
|
152
147
|
function colTrack(cId: string, measuring: boolean) {
|
|
153
148
|
if (measuring) return 'max-content';
|
|
154
149
|
const c = manager.getColumn(cId);
|
|
@@ -291,7 +286,7 @@
|
|
|
291
286
|
data-dt-cell="1"
|
|
292
287
|
data-col-id={cid}
|
|
293
288
|
data-row-index={i}
|
|
294
|
-
class="px-3"
|
|
289
|
+
class="flex h-full w-full items-center px-3"
|
|
295
290
|
onclick={() => onRowClick?.(row)}
|
|
296
291
|
oncontextmenu={(e) => onCellContext(e, row, cid, i)}
|
|
297
292
|
>
|
|
@@ -5,14 +5,19 @@
|
|
|
5
5
|
function portal(node: HTMLElement, target: HTMLElement | null = null) {
|
|
6
6
|
const tgt = target ?? document.body;
|
|
7
7
|
const placeholder = document.createComment('portal-placeholder');
|
|
8
|
-
if (
|
|
9
|
-
|
|
8
|
+
if (node.parentNode) {
|
|
9
|
+
node.parentNode.insertBefore(placeholder, node);
|
|
10
|
+
}
|
|
11
|
+
// Remove any existing menu instances
|
|
12
|
+
const existingMenus = document.querySelectorAll('.context-menu-portal');
|
|
13
|
+
existingMenus.forEach((menu) => menu.remove());
|
|
14
|
+
// Add class for identification
|
|
15
|
+
node.classList.add('context-menu-portal');
|
|
10
16
|
tgt.appendChild(node);
|
|
11
17
|
return {
|
|
12
18
|
destroy() {
|
|
13
19
|
if (node.isConnected) node.remove();
|
|
14
20
|
if (placeholder.isConnected && placeholder.parentNode) {
|
|
15
|
-
placeholder.parentNode.insertBefore(node, placeholder);
|
|
16
21
|
placeholder.remove();
|
|
17
22
|
}
|
|
18
23
|
}
|
|
@@ -65,6 +70,12 @@
|
|
|
65
70
|
q = '';
|
|
66
71
|
x = 0;
|
|
67
72
|
y = 0;
|
|
73
|
+
if (menuEl) {
|
|
74
|
+
menuEl.style.left = '0px';
|
|
75
|
+
menuEl.style.top = '0px';
|
|
76
|
+
menuEl.remove();
|
|
77
|
+
menuEl = null;
|
|
78
|
+
}
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
function hasChildren(it: TContextMenuEntry) {
|
|
@@ -170,40 +181,21 @@
|
|
|
170
181
|
};
|
|
171
182
|
});
|
|
172
183
|
|
|
173
|
-
//
|
|
184
|
+
// Aplicar posición tras abrir o cambiar coords
|
|
174
185
|
$effect(() => {
|
|
175
186
|
if (!open || !menuEl) return;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (nx !== x || ny !== y) {
|
|
181
|
-
x = nx;
|
|
182
|
-
y = ny;
|
|
183
|
-
}
|
|
184
|
-
});
|
|
187
|
+
const rect = menuEl.getBoundingClientRect();
|
|
188
|
+
const { x: nx, y: ny } = clampToViewport(x, y, rect.width, rect.height, 8);
|
|
189
|
+
menuEl.style.left = `${nx}px`;
|
|
190
|
+
menuEl.style.top = `${ny}px`;
|
|
185
191
|
});
|
|
186
192
|
</script>
|
|
187
193
|
|
|
188
194
|
{#if open}
|
|
189
|
-
<!-- BACKDROP -->
|
|
190
|
-
<div
|
|
191
|
-
use:portal={portalTarget}
|
|
192
|
-
role="dialog"
|
|
193
|
-
class="fixed inset-0 z-[2147483646]"
|
|
194
|
-
onclick={() => close()}
|
|
195
|
-
oncontextmenu={(e) => e.preventDefault()}
|
|
196
|
-
aria-modal="true"
|
|
197
|
-
tabindex="0"
|
|
198
|
-
style="pointer-events:auto"
|
|
199
|
-
/>
|
|
200
|
-
|
|
201
|
-
<!-- MENÚ -->
|
|
202
195
|
<div
|
|
203
196
|
bind:this={menuEl}
|
|
204
197
|
use:portal={portalTarget}
|
|
205
|
-
class="fixed z-[2147483647] w-72 rounded-2xl bg-white p-2 shadow-xl ring-1 ring-black/5 dark:bg-gray-900"
|
|
206
|
-
style={`left:${x}px; top:${y}px`}
|
|
198
|
+
class="context-menu-portal fixed z-[2147483647] w-72 rounded-2xl bg-white p-2 shadow-xl ring-1 ring-black/5 dark:bg-gray-900"
|
|
207
199
|
oncontextmenu={(e) => e.preventDefault()}
|
|
208
200
|
>
|
|
209
201
|
<div class="flex items-center gap-1 px-1 py-1">
|
|
@@ -241,42 +233,46 @@
|
|
|
241
233
|
<div
|
|
242
234
|
class="max-h-72 overflow-auto rounded-xl border border-gray-200 p-1 dark:border-gray-800 dark:bg-gray-950"
|
|
243
235
|
>
|
|
244
|
-
{#
|
|
245
|
-
{#
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
236
|
+
{#if filtered.length}
|
|
237
|
+
{#each filtered as it}
|
|
238
|
+
{#if it.kind === 'divider'}
|
|
239
|
+
<div class="my-1 border-t border-gray-200 dark:border-gray-800"></div>
|
|
240
|
+
{:else if it.kind === 'label'}
|
|
241
|
+
<div class="px-3 py-1 text-[11px] tracking-wide uppercase opacity-60">{it.label}</div>
|
|
242
|
+
{:else}
|
|
243
|
+
<button
|
|
244
|
+
class="flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-gray-100 disabled:opacity-50 dark:hover:bg-gray-800"
|
|
245
|
+
role="dialog"
|
|
246
|
+
disabled={it.disabled}
|
|
247
|
+
onclick={() => clickItem(it)}
|
|
248
|
+
>
|
|
249
|
+
<span class="truncate">{it.label}</span>
|
|
250
|
+
<span class="flex items-center gap-2">
|
|
251
|
+
{#if it.shortcut}
|
|
252
|
+
<kbd class="rounded bg-gray-100 px-1 text-[10px] dark:bg-gray-800"
|
|
253
|
+
>{it.shortcut}</kbd
|
|
254
|
+
>
|
|
255
|
+
{/if}
|
|
256
|
+
{#if hasChildren(it)}
|
|
257
|
+
<svg
|
|
258
|
+
width="14"
|
|
259
|
+
height="14"
|
|
260
|
+
viewBox="0 0 24 24"
|
|
261
|
+
class="opacity-60"
|
|
262
|
+
fill="none"
|
|
263
|
+
stroke="currentColor"
|
|
264
|
+
stroke-width="2"
|
|
265
|
+
stroke-linecap="round"
|
|
266
|
+
stroke-linejoin="round"><polyline points="9 18 15 12 9 6" /></svg
|
|
267
|
+
>
|
|
268
|
+
{/if}
|
|
269
|
+
</span>
|
|
270
|
+
</button>
|
|
271
|
+
{/if}
|
|
272
|
+
{/each}
|
|
273
|
+
{:else}
|
|
274
|
+
<div class="my-1 border-t border-gray-200 dark:border-gray-800">No hay resultados</div>
|
|
275
|
+
{/if}
|
|
280
276
|
</div>
|
|
281
277
|
</div>
|
|
282
278
|
{/if}
|