@r2digisolutions/ui 0.22.4 → 0.22.6

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.
@@ -2,11 +2,11 @@
2
2
  import type { Snippet } from 'svelte';
3
3
  import { tick } from 'svelte';
4
4
  import type {
5
+ TContextMenuEntry,
5
6
  TDataTableCellContext,
6
7
  TDataTableColumnDef,
7
8
  TDataTableTableOptions
8
9
  } from './core/types.js';
9
- import type { Entry } from './components/ContextMenu.svelte';
10
10
  import type { FilterField } from './core/filters/types.js';
11
11
  import { DataTableManager } from './core/DataTableManager.svelte';
12
12
  import FilterPanel from './components/FilterPanel.svelte';
@@ -20,7 +20,7 @@
20
20
  filters?: Snippet;
21
21
  options: TDataTableTableOptions<T>;
22
22
  rowId?: (row: T) => any;
23
- actions?: (rows: T[], ctx?: TDataTableCellContext<T> | null) => Entry[];
23
+ actions?: (rows: T[], ctx?: TDataTableCellContext<T> | null) => TContextMenuEntry[];
24
24
  rowActions?: (row: T) => any;
25
25
  onRowClick?: (row: T) => void;
26
26
  density?: 'compact' | 'normal' | 'comfortable';
@@ -259,7 +259,7 @@
259
259
  {#if manager.state.hiddenColumns.length > 0}
260
260
  {#if expandIconPosition === 'start'}
261
261
  <button
262
- class="rounded-lg p-1 hover:bg-gray-100 dark:hover:bg-gray-800"
262
+ class="cursor-pointer rounded-lg p-1 hover:bg-gray-100 dark:hover:bg-gray-800"
263
263
  title={manager.isExpanded(rowId(row)) ? 'Ocultar detalles' : 'Ver detalles'}
264
264
  onclick={() => manager.toggleExpand(rowId(row))}
265
265
  >
@@ -300,7 +300,7 @@
300
300
  <div class="inline-flex items-center gap-2">
301
301
  {#if expandIconPosition === 'end' && manager.state.hiddenColumns.length > 0}
302
302
  <button
303
- class="rounded-lg p-1 hover:bg-gray-100 dark:hover:bg-gray-800"
303
+ class="cursor-pointer rounded-lg p-1 hover:bg-gray-100 dark:hover:bg-gray-800"
304
304
  title={manager.isExpanded(rowId(row)) ? 'Ocultar detalles' : 'Ver detalles'}
305
305
  onclick={() => manager.toggleExpand(rowId(row))}
306
306
  >
@@ -328,7 +328,6 @@
328
328
  </div>
329
329
  {/if}
330
330
 
331
- <!-- COLLAPSE: fila nueva de ancho completo (evita solapes) -->
332
331
  {#if manager.isExpanded(rowId(row))}
333
332
  <div class="col-span-full px-3 pt-1 pb-3">
334
333
  <div class="grid gap-3 sm:grid-cols-2 md:grid-cols-3">
@@ -336,7 +335,7 @@
336
335
  {#key hid}
337
336
  {@const col = manager.columns.find((cc) => cc.id === hid)}
338
337
  {#if col}
339
- <div class="rounded-xl border p-3 dark:border-gray-800">
338
+ <div class="rounded-xl border border-gray-200 p-3 dark:border-gray-800">
340
339
  <div class="mb-1 text-[11px] tracking-wide uppercase opacity-60">
341
340
  {col.responsiveLabel ?? col.header}
342
341
  </div>
@@ -1,12 +1,11 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { TDataTableCellContext, TDataTableTableOptions } from './core/types.js';
3
- import type { Entry } from './components/ContextMenu.svelte';
2
+ import type { TContextMenuEntry, TDataTableCellContext, TDataTableTableOptions } from './core/types.js';
4
3
  import type { FilterField } from './core/filters/types.js';
5
4
  interface Props<T> {
6
5
  filters?: Snippet;
7
6
  options: TDataTableTableOptions<T>;
8
7
  rowId?: (row: T) => any;
9
- actions?: (rows: T[], ctx?: TDataTableCellContext<T> | null) => Entry[];
8
+ actions?: (rows: T[], ctx?: TDataTableCellContext<T> | null) => TContextMenuEntry[];
10
9
  rowActions?: (row: T) => any;
11
10
  onRowClick?: (row: T) => void;
12
11
  density?: 'compact' | 'normal' | 'comfortable';
@@ -1,18 +1,8 @@
1
- <script module lang="ts">
2
- export type Entry = {
3
- id: string;
4
- label?: string;
5
- shortcut?: string;
6
- onClick?: () => void;
7
- disabled?: boolean;
8
- children?: Entry[];
9
- kind?: 'item' | 'divider' | 'label';
10
- };
11
- </script>
12
-
13
1
  <script lang="ts">
2
+ import type { TContextMenuEntry } from '../core/types.js';
3
+
14
4
  type Props = {
15
- items?: Entry[];
5
+ items?: TContextMenuEntry[];
16
6
  x?: number;
17
7
  y?: number;
18
8
  open?: boolean;
@@ -30,7 +20,7 @@
30
20
  context = null
31
21
  }: Props = $props();
32
22
 
33
- let stack = $state<{ label: string; items: Entry[] }[]>([]);
23
+ let stack = $state<{ label: string; items: TContextMenuEntry[] }[]>([]);
34
24
  let q = $state('');
35
25
 
36
26
  const current = $derived(stack.length ? stack[stack.length - 1] : { label: title, items });
@@ -41,11 +31,11 @@
41
31
  q = '';
42
32
  }
43
33
 
44
- function hasChildren(it: Entry) {
34
+ function hasChildren(it: TContextMenuEntry) {
45
35
  return !!(it.children && it.children.length);
46
36
  }
47
37
 
48
- function clickItem(it: Entry) {
38
+ function clickItem(it: TContextMenuEntry) {
49
39
  if (it.disabled) return;
50
40
  if (hasChildren(it)) {
51
41
  stack.push({ label: it.label ?? '', items: it.children! });
@@ -58,7 +48,7 @@
58
48
  }
59
49
  }
60
50
 
61
- function matches(it: Entry, query: string): boolean {
51
+ function matches(it: TContextMenuEntry, query: string): boolean {
62
52
  if (it.kind === 'divider') return true;
63
53
  const lbl = (it.label ?? '').toLowerCase();
64
54
  if (lbl.includes(query)) return true;
@@ -72,7 +62,7 @@
72
62
  let arr = query ? list.filter((it) => matches(it, query)) : list.slice();
73
63
 
74
64
  // limpiar divisores (sin duplicados, ni al principio/fin)
75
- const out: Entry[] = [];
65
+ const out: TContextMenuEntry[] = [];
76
66
  let prevDiv = false;
77
67
  for (const it of arr) {
78
68
  if (it.kind === 'divider') {
@@ -1,14 +1,6 @@
1
- export type Entry = {
2
- id: string;
3
- label?: string;
4
- shortcut?: string;
5
- onClick?: () => void;
6
- disabled?: boolean;
7
- children?: Entry[];
8
- kind?: 'item' | 'divider' | 'label';
9
- };
1
+ import type { TContextMenuEntry } from '../core/types.js';
10
2
  type Props = {
11
- items?: Entry[];
3
+ items?: TContextMenuEntry[];
12
4
  x?: number;
13
5
  y?: number;
14
6
  open?: boolean;
@@ -1,7 +1,7 @@
1
1
  export type TDataTableRowId = string | number;
2
2
  export type TDataTableSortDir = 'asc' | 'desc' | null;
3
3
  export type TDataTableColumnKey<T> = Extract<keyof T, string>;
4
- export type Accessor<T, R = any> = (row: T) => R;
4
+ export type TDataTableAccessor<T, R = any> = (row: T) => R;
5
5
  export type TDataTableColumnType = 'text' | 'number' | 'currency' | 'date' | 'datetime' | 'boolean' | 'badge' | 'link' | 'code';
6
6
  type TDataTableBaseColumn<T> = {
7
7
  header: string;
@@ -28,7 +28,7 @@ export type TDataTableKeyColumn<T, K extends TDataTableColumnKey<T> = TDataTable
28
28
  /** Columna virtual (id libre), requiere accessor explícito */
29
29
  export type TDataTableVirtualColumn<T> = TDataTableBaseColumn<T> & {
30
30
  id: string;
31
- accessor: Accessor<T>;
31
+ accessor: TDataTableAccessor<T>;
32
32
  renderCell?: (row: T) => any;
33
33
  renderCollapsed?: (row: T) => any;
34
34
  };
@@ -98,4 +98,13 @@ export type TDataTableCellContext<T> = {
98
98
  columnIndex: number | null;
99
99
  event: MouseEvent;
100
100
  };
101
+ export type TContextMenuEntry = {
102
+ id: string;
103
+ label?: string;
104
+ shortcut?: string;
105
+ onClick?: () => void;
106
+ disabled?: boolean;
107
+ children?: TContextMenuEntry[];
108
+ kind?: 'item' | 'divider' | 'label';
109
+ };
101
110
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@r2digisolutions/ui",
3
- "version": "0.22.4",
3
+ "version": "0.22.6",
4
4
  "private": false,
5
5
  "packageManager": "bun@1.2.22",
6
6
  "publishConfig": {