@moontra/moonui-pro
Version:
Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components
152 lines (126 loc) • 4.53 kB
text/typescript
export interface DataProcessor<T = any> {
filter: (data: T[], predicate: (item: T) => boolean) => T[]
sort: (data: T[], key: keyof T, direction?: 'asc' | 'desc') => T[]
group: (data: T[], key: keyof T) => Record<string, T[]>
aggregate: (data: T[], key: keyof T, operation: 'sum' | 'avg' | 'min' | 'max' | 'count') => number
paginate: (data: T[], page: number, pageSize: number) => T[]
search: (data: T[], query: string, searchKeys?: (keyof T)[]) => T[]
transform: <U>(data: T[], transformer: (item: T) => U) => U[]
}
export function createDataProcessor<T = any>(): DataProcessor<T> {
return {
filter: (data: T[], predicate: (item: T) => boolean) => {
return data.filter(predicate)
},
sort: (data: T[], key: keyof T, direction: 'asc' | 'desc' = 'asc') => {
return [...data].sort((a, b) => {
const aVal = a[key]
const bVal = b[key]
if (aVal === bVal) return 0
const comparison = aVal < bVal ? -1 : 1
return direction === 'asc' ? comparison : -comparison
})
},
group: (data: T[], key: keyof T) => {
return data.reduce((groups, item) => {
const groupKey = String(item[key])
if (!groups[groupKey]) {
groups[groupKey] = []
}
groups[groupKey].push(item)
return groups
}, {} as Record<string, T[]>)
},
aggregate: (data: T[], key: keyof T, operation: 'sum' | 'avg' | 'min' | 'max' | 'count') => {
const values = data.map(item => Number(item[key])).filter(val => !isNaN(val))
if (values.length === 0) return 0
switch (operation) {
case 'sum':
return values.reduce((sum, val) => sum + val, 0)
case 'avg':
return values.reduce((sum, val) => sum + val, 0) / values.length
case 'min':
return Math.min(...values)
case 'max':
return Math.max(...values)
case 'count':
return values.length
default:
return 0
}
},
paginate: (data: T[], page: number, pageSize: number) => {
const startIndex = (page - 1) * pageSize
const endIndex = startIndex + pageSize
return data.slice(startIndex, endIndex)
},
search: (data: T[], query: string, searchKeys?: (keyof T)[]) => {
if (!query.trim()) return data
const lowerQuery = query.toLowerCase()
return data.filter(item => {
const keysToSearch = searchKeys || Object.keys(item as Record<string, any>) as (keyof T)[]
return keysToSearch.some(key => {
const value = item[key]
if (value == null) return false
return String(value).toLowerCase().includes(lowerQuery)
})
})
},
transform: <U>(data: T[], transformer: (item: T) => U) => {
return data.map(transformer)
}
}
}
// Utility functions for common data operations
export function calculatePercentageChange(current: number, previous: number): number {
if (previous === 0) return current > 0 ? 100 : 0
return ((current - previous) / previous) * 100
}
export function formatNumber(value: number, options?: {
decimals?: number
currency?: string
percentage?: boolean
compact?: boolean
}): string {
const { decimals = 2, currency, percentage = false, compact = false } = options || {}
if (percentage) {
return `${value.toFixed(decimals)}%`
}
if (currency) {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
}).format(value)
}
if (compact && Math.abs(value) >= 1000) {
return new Intl.NumberFormat('en-US', {
notation: 'compact',
minimumFractionDigits: 0,
maximumFractionDigits: 1,
}).format(value)
}
return value.toFixed(decimals)
}
export function generateDateRange(start: Date, end: Date, interval: 'day' | 'week' | 'month' = 'day'): Date[] {
const dates: Date[] = []
const current = new Date(start)
while (current <= end) {
dates.push(new Date(current))
switch (interval) {
case 'day':
current.setDate(current.getDate() + 1)
break
case 'week':
current.setDate(current.getDate() + 7)
break
case 'month':
current.setMonth(current.getMonth() + 1)
break
}
}
return dates
}
// debounce function removed to avoid conflicts with @moontra/moonui
// Use debounce from @moontra/moonui instead