neogestify-ui-components 2.1.0 → 2.2.2
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/README.md +46 -1
- package/dist/components/ElementLibraryBuilder/index.d.mts +5 -0
- package/dist/components/ElementLibraryBuilder/index.d.ts +5 -0
- package/dist/components/ElementLibraryBuilder/index.js +689 -0
- package/dist/components/ElementLibraryBuilder/index.js.map +1 -0
- package/dist/components/ElementLibraryBuilder/index.mjs +687 -0
- package/dist/components/ElementLibraryBuilder/index.mjs.map +1 -0
- package/dist/components/VenueMapEditor/index.d.mts +18 -2
- package/dist/components/VenueMapEditor/index.d.ts +18 -2
- package/dist/components/VenueMapEditor/index.js +75 -3
- package/dist/components/VenueMapEditor/index.js.map +1 -1
- package/dist/components/VenueMapEditor/index.mjs +75 -4
- package/dist/components/VenueMapEditor/index.mjs.map +1 -1
- package/dist/components/html/index.d.mts +37 -4
- package/dist/components/html/index.d.ts +37 -4
- package/dist/components/html/index.js +135 -12
- package/dist/components/html/index.js.map +1 -1
- package/dist/components/html/index.mjs +135 -12
- package/dist/components/html/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +603 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +602 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/ElementLibraryBuilder/builder.tsx +400 -0
- package/src/components/ElementLibraryBuilder/index.ts +1 -0
- package/src/components/VenueMapEditor/components/ElementNode.tsx +22 -0
- package/src/components/VenueMapEditor/components/PropertiesPanel.tsx +17 -4
- package/src/components/VenueMapEditor/components/Toolbar.tsx +14 -4
- package/src/components/VenueMapEditor/index.ts +2 -0
- package/src/components/VenueMapEditor/types.ts +11 -1
- package/src/components/VenueMapEditor/utils/svgParser.ts +33 -0
- package/src/components/html/Table.tsx +205 -38
- package/src/index.ts +1 -0
|
@@ -1,60 +1,227 @@
|
|
|
1
|
-
import { type ReactNode } from 'react';
|
|
1
|
+
import { type ReactNode, type CSSProperties } from 'react';
|
|
2
|
+
|
|
3
|
+
type TableVariant = 'default' | 'striped' | 'bordered' | 'minimal' | 'custom';
|
|
4
|
+
type TableSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
|
|
6
|
+
interface ColumnDef {
|
|
7
|
+
/** Contenido del encabezado */
|
|
8
|
+
header: ReactNode;
|
|
9
|
+
/** Clase CSS adicional para toda la columna (th + td) */
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Alinear el contenido de esta columna */
|
|
12
|
+
align?: 'left' | 'center' | 'right';
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
interface TableProps {
|
|
4
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Definición de columnas con encabezado y opciones por columna.
|
|
18
|
+
* Si pasas strings simples, los usa como encabezados sin configuración extra.
|
|
19
|
+
*/
|
|
20
|
+
columns: (ColumnDef | ReactNode)[];
|
|
21
|
+
|
|
22
|
+
/** Filas de la tabla. Cada fila es un arreglo de celdas. */
|
|
5
23
|
rows: ReactNode[][];
|
|
6
|
-
|
|
24
|
+
|
|
25
|
+
/** Estilo visual de la tabla. Default: 'default' */
|
|
26
|
+
variant?: TableVariant;
|
|
27
|
+
|
|
28
|
+
/** Tamaño de padding de celdas. Default: 'md' */
|
|
29
|
+
size?: TableSize;
|
|
30
|
+
|
|
31
|
+
/** Clase CSS adicional para el wrapper `<div>` externo */
|
|
7
32
|
className?: string;
|
|
33
|
+
|
|
34
|
+
/** Clase CSS adicional para el `<table>` */
|
|
35
|
+
tableClassName?: string;
|
|
36
|
+
|
|
37
|
+
/** Clase CSS adicional para cada `<th>` */
|
|
8
38
|
thClassName?: string;
|
|
39
|
+
|
|
40
|
+
/** Clase CSS adicional para cada `<td>` */
|
|
9
41
|
tdClassName?: string;
|
|
42
|
+
|
|
43
|
+
/** Clase CSS adicional para cada `<tr>` del body */
|
|
44
|
+
trClassName?: string | ((rowIndex: number) => string);
|
|
45
|
+
|
|
46
|
+
/** Texto o nodo a mostrar cuando `rows` está vacío */
|
|
47
|
+
emptyState?: ReactNode;
|
|
48
|
+
|
|
49
|
+
/** Callback al hacer click en una fila */
|
|
50
|
+
onRowClick?: (rowIndex: number) => void;
|
|
51
|
+
|
|
52
|
+
/** Si true, no muestra thead */
|
|
53
|
+
hideHeader?: boolean;
|
|
54
|
+
|
|
55
|
+
/** Estilos inline para el `<table>` */
|
|
56
|
+
style?: CSSProperties;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
60
|
+
|
|
61
|
+
function isColumnDef(col: ColumnDef | ReactNode): col is ColumnDef {
|
|
62
|
+
return typeof col === 'object' && col !== null && 'header' in (col as object);
|
|
10
63
|
}
|
|
11
64
|
|
|
65
|
+
function resolveColumn(col: ColumnDef | ReactNode): ColumnDef {
|
|
66
|
+
if (isColumnDef(col)) return col;
|
|
67
|
+
return { header: col };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const ALIGN_CLASS: Record<string, string> = {
|
|
71
|
+
left: 'text-left',
|
|
72
|
+
center: 'text-center',
|
|
73
|
+
right: 'text-right',
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const SIZE_TH: Record<TableSize, string> = {
|
|
77
|
+
sm: 'px-2 py-1.5 text-xs',
|
|
78
|
+
md: 'px-3 py-2.5 text-xs',
|
|
79
|
+
lg: 'px-4 py-3.5 text-sm',
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const SIZE_TD: Record<TableSize, string> = {
|
|
83
|
+
sm: 'px-2 py-1.5 text-xs',
|
|
84
|
+
md: 'px-3 py-2.5 text-sm',
|
|
85
|
+
lg: 'px-4 py-3.5 text-sm',
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const VARIANT_TABLE: Record<TableVariant, string> = {
|
|
89
|
+
default: 'w-full min-w-full table-auto',
|
|
90
|
+
striped: 'w-full min-w-full table-auto',
|
|
91
|
+
bordered: 'w-full min-w-full table-auto border border-gray-300 dark:border-gray-600',
|
|
92
|
+
minimal: 'w-full min-w-full table-auto',
|
|
93
|
+
custom: 'w-full min-w-full table-auto',
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const VARIANT_THEAD: Record<TableVariant, string> = {
|
|
97
|
+
default: 'bg-gray-100 dark:bg-gray-700',
|
|
98
|
+
striped: 'bg-gray-100 dark:bg-gray-700',
|
|
99
|
+
bordered: 'bg-gray-100 dark:bg-gray-700',
|
|
100
|
+
minimal: '',
|
|
101
|
+
custom: '',
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const VARIANT_TH: Record<TableVariant, string> = {
|
|
105
|
+
default: 'font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300',
|
|
106
|
+
striped: 'font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300',
|
|
107
|
+
bordered: 'font-semibold uppercase tracking-wider text-gray-600 dark:text-gray-300 border border-gray-300 dark:border-gray-600',
|
|
108
|
+
minimal: 'font-semibold text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-700',
|
|
109
|
+
custom: '',
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const VARIANT_TR: Record<TableVariant, (i: number) => string> = {
|
|
113
|
+
default: () => 'bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/60 transition-colors',
|
|
114
|
+
striped: (i) => `${i % 2 === 0 ? 'bg-white dark:bg-gray-800' : 'bg-gray-50 dark:bg-gray-700/40'} hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-colors`,
|
|
115
|
+
bordered: () => 'bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/60 transition-colors',
|
|
116
|
+
minimal: () => 'hover:bg-gray-50 dark:hover:bg-gray-800/60 transition-colors',
|
|
117
|
+
custom: () => '',
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const VARIANT_TD: Record<TableVariant, string> = {
|
|
121
|
+
default: 'text-gray-700 dark:text-gray-300',
|
|
122
|
+
striped: 'text-gray-700 dark:text-gray-300',
|
|
123
|
+
bordered: 'text-gray-700 dark:text-gray-300 border border-gray-200 dark:border-gray-700',
|
|
124
|
+
minimal: 'text-gray-700 dark:text-gray-300 border-b border-gray-100 dark:border-gray-800',
|
|
125
|
+
custom: '',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const VARIANT_TBODY_DIVIDER: Record<TableVariant, string> = {
|
|
129
|
+
default: 'divide-y divide-gray-200 dark:divide-gray-700',
|
|
130
|
+
striped: '',
|
|
131
|
+
bordered: '',
|
|
132
|
+
minimal: '',
|
|
133
|
+
custom: '',
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// ─── Component ───────────────────────────────────────────────────────────────
|
|
137
|
+
|
|
12
138
|
export function Table({
|
|
13
|
-
|
|
139
|
+
columns,
|
|
14
140
|
rows,
|
|
15
141
|
variant = 'default',
|
|
142
|
+
size = 'md',
|
|
16
143
|
className = '',
|
|
144
|
+
tableClassName = '',
|
|
17
145
|
thClassName = '',
|
|
18
|
-
tdClassName = ''
|
|
146
|
+
tdClassName = '',
|
|
147
|
+
trClassName,
|
|
148
|
+
emptyState,
|
|
149
|
+
onRowClick,
|
|
150
|
+
hideHeader = false,
|
|
151
|
+
style,
|
|
19
152
|
}: TableProps) {
|
|
20
|
-
const
|
|
21
|
-
? 'w-full table-auto border-collapse border border-gray-300 dark:border-gray-600 min-w-full'
|
|
22
|
-
: '';
|
|
23
|
-
|
|
24
|
-
const baseThClass = variant === 'default'
|
|
25
|
-
? 'border border-gray-300 dark:border-gray-600 px-4 py-2 text-left text-gray-900 dark:text-white'
|
|
26
|
-
: '';
|
|
153
|
+
const cols = columns.map(resolveColumn);
|
|
27
154
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
: '';
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const tdClass = `${baseTdClass} ${tdClassName}`.trim();
|
|
155
|
+
const resolvedTrClass = (i: number): string => {
|
|
156
|
+
const variantCls = VARIANT_TR[variant](i);
|
|
157
|
+
const clickCls = onRowClick ? 'cursor-pointer' : '';
|
|
158
|
+
const customCls = typeof trClassName === 'function' ? trClassName(i) : (trClassName ?? '');
|
|
159
|
+
return `${variantCls} ${clickCls} ${customCls}`.trim();
|
|
160
|
+
};
|
|
35
161
|
|
|
36
162
|
return (
|
|
37
|
-
<div className=
|
|
38
|
-
<table
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
163
|
+
<div className={`overflow-x-auto w-full ${className}`.trim()}>
|
|
164
|
+
<table
|
|
165
|
+
className={`${VARIANT_TABLE[variant]} ${tableClassName}`.trim()}
|
|
166
|
+
style={style}
|
|
167
|
+
>
|
|
168
|
+
{!hideHeader && (
|
|
169
|
+
<thead className={VARIANT_THEAD[variant]}>
|
|
170
|
+
<tr>
|
|
171
|
+
{cols.map((col, i) => (
|
|
172
|
+
<th
|
|
173
|
+
key={i}
|
|
174
|
+
className={[
|
|
175
|
+
SIZE_TH[size],
|
|
176
|
+
VARIANT_TH[variant],
|
|
177
|
+
ALIGN_CLASS[col.align ?? 'left'],
|
|
178
|
+
col.className ?? '',
|
|
179
|
+
thClassName,
|
|
180
|
+
].filter(Boolean).join(' ')}
|
|
181
|
+
>
|
|
182
|
+
{col.header}
|
|
183
|
+
</th>
|
|
55
184
|
))}
|
|
56
185
|
</tr>
|
|
57
|
-
|
|
186
|
+
</thead>
|
|
187
|
+
)}
|
|
188
|
+
<tbody className={VARIANT_TBODY_DIVIDER[variant]}>
|
|
189
|
+
{rows.length === 0 ? (
|
|
190
|
+
<tr>
|
|
191
|
+
<td
|
|
192
|
+
colSpan={cols.length}
|
|
193
|
+
className={`${SIZE_TD[size]} text-center text-gray-400 dark:text-gray-500 py-8`}
|
|
194
|
+
>
|
|
195
|
+
{emptyState ?? 'Sin datos'}
|
|
196
|
+
</td>
|
|
197
|
+
</tr>
|
|
198
|
+
) : (
|
|
199
|
+
rows.map((row, rowIndex) => (
|
|
200
|
+
<tr
|
|
201
|
+
key={rowIndex}
|
|
202
|
+
className={resolvedTrClass(rowIndex)}
|
|
203
|
+
onClick={onRowClick ? () => onRowClick(rowIndex) : undefined}
|
|
204
|
+
>
|
|
205
|
+
{row.map((cell, cellIndex) => {
|
|
206
|
+
const col = cols[cellIndex];
|
|
207
|
+
return (
|
|
208
|
+
<td
|
|
209
|
+
key={cellIndex}
|
|
210
|
+
className={[
|
|
211
|
+
SIZE_TD[size],
|
|
212
|
+
VARIANT_TD[variant],
|
|
213
|
+
ALIGN_CLASS[col?.align ?? 'left'],
|
|
214
|
+
col?.className ?? '',
|
|
215
|
+
tdClassName,
|
|
216
|
+
].filter(Boolean).join(' ')}
|
|
217
|
+
>
|
|
218
|
+
{cell}
|
|
219
|
+
</td>
|
|
220
|
+
);
|
|
221
|
+
})}
|
|
222
|
+
</tr>
|
|
223
|
+
))
|
|
224
|
+
)}
|
|
58
225
|
</tbody>
|
|
59
226
|
</table>
|
|
60
227
|
</div>
|
package/src/index.ts
CHANGED