@moontra/moonui-pro
Version:
Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components
156 lines (132 loc) • 4.16 kB
text/typescript
/**
* Export utilities for DataTable component
*/
export type ExportFormat = 'csv' | 'json' | 'xlsx';
export interface ExportOptions {
filename?: string;
format: ExportFormat;
columns?: string[];
includeHeaders?: boolean;
}
/**
* Convert data to CSV format
*/
export function dataToCSV<T extends Record<string, any>>(
data: T[],
columns?: string[],
includeHeaders = true
): string {
if (data.length === 0) return '';
// Get columns from first item if not provided
const cols = columns || Object.keys(data[0]);
// Build CSV content
const rows: string[] = [];
// Add headers
if (includeHeaders) {
const headers = cols.map(col => {
// Handle column names with special characters
const value = String(col);
return value.includes(',') || value.includes('"') || value.includes('\n')
? `"${value.replace(/"/g, '""')}"`
: value;
});
rows.push(headers.join(','));
}
// Add data rows
data.forEach(item => {
const row = cols.map(col => {
const value = item[col];
// Handle different value types
if (value === null || value === undefined) return '';
if (value instanceof Date) return value.toISOString();
if (typeof value === 'object') return JSON.stringify(value);
const stringValue = String(value);
return stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')
? `"${stringValue.replace(/"/g, '""')}"`
: stringValue;
});
rows.push(row.join(','));
});
return rows.join('\n');
}
/**
* Convert data to JSON format
*/
export function dataToJSON<T>(data: T[], columns?: string[]): string {
if (!columns || columns.length === 0) {
return JSON.stringify(data, null, 2);
}
// Filter data to include only specified columns
const filteredData = data.map(item => {
const filtered: Record<string, any> = {};
columns.forEach(col => {
if (col in (item as any)) {
filtered[col] = (item as any)[col];
}
});
return filtered;
});
return JSON.stringify(filteredData, null, 2);
}
/**
* Download data as a file
*/
export function downloadFile(content: string, filename: string, mimeType: string): void {
const blob = new Blob([content], { type: mimeType });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
// Cleanup
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
/**
* Export data to the specified format
*/
export async function exportData<T extends Record<string, any>>(
data: T[],
options: ExportOptions
): Promise<void> {
const { format, filename = 'data-export', columns, includeHeaders = true } = options;
let content: string;
let mimeType: string;
let extension: string;
switch (format) {
case 'csv':
content = dataToCSV(data, columns, includeHeaders);
mimeType = 'text/csv;charset=utf-8;';
extension = 'csv';
break;
case 'json':
content = dataToJSON(data, columns);
mimeType = 'application/json;charset=utf-8;';
extension = 'json';
break;
case 'xlsx':
// For XLSX, we'll need to use a library like xlsx or exceljs
// For now, we'll throw an error indicating it's not implemented
throw new Error('XLSX export requires additional dependencies. Use CSV format instead.');
default:
throw new Error(`Unsupported export format: ${format}`);
}
const finalFilename = `${filename}-${new Date().toISOString().split('T')[0]}.${extension}`;
downloadFile(content, finalFilename, mimeType);
}
/**
* Get visible columns from column definitions
*/
export function getVisibleColumns<T>(
columns: Array<{ id?: string; accessorKey?: string; header?: any }>,
columnVisibility: Record<string, boolean>
): string[] {
return columns
.filter(col => {
const key = col.id || col.accessorKey;
return key && columnVisibility[key] !== false;
})
.map(col => col.id || col.accessorKey!)
.filter(Boolean);
}