delon-util by aiskillstore
@delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system.
Content & Writing
85 Stars
2 Forks
Updated Jan 19, 2026, 04:39 AM
Why Use This
This skill provides specialized capabilities for aiskillstore's codebase.
Use Cases
- Developing new features in the aiskillstore repository
- Refactoring existing code to follow aiskillstore standards
- Understanding and working with aiskillstore's codebase structure
Install Guide
2 steps- 1
Skip this step if Ananke is already installed.
- 2
Skill Snapshot
Auto scan of skill assets. Informational only.
Valid SKILL.md
Checks against SKILL.md specification
Source & Community
Skill Stats
SKILL.md 470 Lines
Total Files 1
Total Size 0 B
License NOASSERTION
--- name: delon-util description: '@delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system.' --- # @delon/util - Utility Functions Library Trigger patterns: "utility", "helper", "@delon/util", "format", "deepCopy", "deepMerge" ## Overview @delon/util provides a comprehensive collection of utility functions for common data manipulation tasks in ng-alain applications. **Package**: @delon/[email protected] ## Categories ### 1. Array Utilities (`array/`) #### deepCopy - Deep Copy Arrays/Objects ```typescript import { deepCopy } from '@delon/util/array'; const original = { name: '任務', items: [1, 2, 3], meta: { id: 1 } }; const copy = deepCopy(original); // Changes to copy won't affect original copy.items.push(4); console.log(original.items); // [1, 2, 3] console.log(copy.items); // [1, 2, 3, 4] ``` **Use Cases**: - Clone state objects for immutability - Create independent copies before mutations - Deep cloning form data #### deepMerge - Deep Merge Objects ```typescript import { deepMerge } from '@delon/util/array'; const defaults = { config: { theme: 'light', size: 'default' }, features: ['dashboard'] }; const custom = { config: { theme: 'dark' }, features: ['reports'] }; const merged = deepMerge(defaults, custom); // Result: { // config: { theme: 'dark', size: 'default' }, // features: ['dashboard', 'reports'] // } ``` #### Other Array Functions ```typescript import { groupBy, // Group array by property uniq, // Remove duplicates uniqBy, // Remove duplicates by property orderBy // Sort array by properties } from '@delon/util/array'; // Group tasks by status const grouped = groupBy(tasks, 'status'); // { pending: [...], completed: [...] } // Remove duplicate IDs const uniqueIds = uniq([1, 2, 2, 3]); // [1, 2, 3] // Remove duplicate tasks by ID const uniqueTasks = uniqBy(tasks, 'id'); // Sort tasks const sorted = orderBy(tasks, ['priority', 'createdAt'], ['asc', 'desc']); ``` ### 2. String Utilities (`string/`) #### format - String Formatting ```typescript import { format } from '@delon/util/string'; // Template interpolation const message = format('任務 {0} 已指派給 {1}', taskName, userName); // Named parameters const message2 = format('任務 {name} 的狀態為 {status}', { name: '地基施工', status: '進行中' }); ``` #### Other String Functions ```typescript import { toCamelCase, // Convert to camelCase toPascalCase, // Convert to PascalCase toKebabCase, // Convert to kebab-case toSnakeCase, // Convert to snake_case truncate // Truncate with ellipsis } from '@delon/util/string'; toCamelCase('task-name'); // 'taskName' toPascalCase('task-name'); // 'TaskName' toKebabCase('TaskName'); // 'task-name' toSnakeCase('TaskName'); // 'task_name' truncate('Long text...', 10); // 'Long te...' ``` ### 3. Date Utilities (`date/`) #### getTimeDistance - Get Time Ranges ```typescript import { getTimeDistance } from '@delon/util/date'; // Get today's date range const today = getTimeDistance('today'); // [Date(2024-12-25 00:00:00), Date(2024-12-25 23:59:59)] // Get this week's date range const week = getTimeDistance('week'); // Get this month's date range const month = getTimeDistance('month'); // Get this year's date range const year = getTimeDistance('year'); // Custom range with offset const lastWeek = getTimeDistance('week', -1); ``` **Supported Types**: - `'today'` - Current day - `'week'` - Current week (Sunday to Saturday) - `'month'` - Current month - `'year'` - Current year - Custom offset (negative for past, positive for future) #### formatDistanceToNow - Relative Time ```typescript import { formatDistanceToNow } from '@delon/util/date'; const createdAt = new Date('2024-12-20'); const relative = formatDistanceToNow(createdAt); // "5 days ago" const futureDate = new Date('2024-12-30'); const future = formatDistanceToNow(futureDate); // "in 5 days" ``` ### 4. Number Utilities (`number/`) #### currency - Currency Formatting ```typescript import { currency } from '@delon/util/number'; // Format as currency currency(1234567.89); // "$1,234,567.89" currency(1234567.89, { unit: '¥' }); // "¥1,234,567.89" currency(1234.5, { precision: 0 }); // "$1,235" ``` #### Other Number Functions ```typescript import { toFixed, // Round to fixed decimals toPercent, // Convert to percentage toThousands // Add thousands separators } from '@delon/util/number'; toFixed(1.2345, 2); // "1.23" toPercent(0.1234); // "12.34%" toPercent(0.1234, 1); // "12.3%" toThousands(1234567); // "1,234,567" ``` ### 5. Browser Utilities (`browser/`) #### copyToClipboard - Copy to Clipboard ```typescript import { copy } from '@delon/util/browser'; async copyTaskLink(taskId: string) { const link = `${window.location.origin}/tasks/${taskId}`; const success = await copy(link); if (success) { this.messageService.success('連結已複製'); } else { this.messageService.error('複製失敗'); } } ``` #### Other Browser Functions ```typescript import { scrollToTop, // Smooth scroll to top deepGet, // Get nested object property deepSet, // Set nested object property isEmpty, // Check if value is empty isEqual, // Deep equality check updateHostClass // Update host element classes } from '@delon/util/browser'; scrollToTop(); scrollToTop({ duration: 500 }); const value = deepGet(obj, 'user.profile.name'); deepSet(obj, 'user.profile.name', 'New Name'); isEmpty(null); // true isEmpty(''); // true isEmpty([]); // true isEmpty({}); // true isEqual({ a: 1 }, { a: 1 }); // true ``` ## Real-World Examples ### Task Management Utilities ```typescript import { Component, signal, computed, inject } from '@angular/core'; import { deepCopy, groupBy, orderBy } from '@delon/util/array'; import { format } from '@delon/util/string'; import { getTimeDistance } from '@delon/util/date'; import { copy } from '@delon/util/browser'; import { NzMessageService } from 'ng-zorro-antd/message'; @Component({ selector: 'app-task-list', standalone: true, template: ` <nz-card> <div nz-row [nzGutter]="16"> @for (group of groupedTasks() | keyvalue; track group.key) { <div nz-col [nzSpan]="8"> <h3>{{ group.key }} ({{ group.value.length }})</h3> @for (task of group.value; track task.id) { <nz-card> <h4>{{ task.title }}</h4> <p>{{ formatTaskInfo(task) }}</p> <button nz-button (click)="copyTaskLink(task.id)"> 複製連結 </button> </nz-card> } </div> } </div> </nz-card> ` }) export class TaskListComponent { private messageService = inject(NzMessageService); // Original tasks from service tasks = signal<Task[]>([]); // Group tasks by status using @delon/util groupedTasks = computed(() => groupBy(this.sortedTasks(), 'status') ); // Sort tasks by priority and date sortedTasks = computed(() => orderBy( this.tasks(), ['priority', 'createdAt'], ['asc', 'desc'] ) ); // Format task information formatTaskInfo(task: Task): string { return format( '優先級: {priority}, 建立於 {date}', { priority: task.priority, date: this.formatDate(task.createdAt) } ); } // Copy task link to clipboard async copyTaskLink(taskId: string): Promise<void> { const link = `${window.location.origin}/tasks/${taskId}`; const success = await copy(link); if (success) { this.messageService.success('任務連結已複製'); } else { this.messageService.error('複製失敗,請手動複製'); } } // Clone task for editing cloneTaskForEdit(task: Task): Task { return deepCopy(task); } // Get this week's tasks getThisWeekTasks(): Task[] { const [start, end] = getTimeDistance('week'); return this.tasks().filter(t => t.createdAt >= start && t.createdAt <= end ); } private formatDate(date: Date): string { return format( '{year}-{month}-{day}', { year: date.getFullYear(), month: String(date.getMonth() + 1).padStart(2, '0'), day: String(date.getDate()).padStart(2, '0') } ); } } ``` ### Form Data Utilities ```typescript import { Component, signal } from '@angular/core'; import { deepCopy, deepMerge } from '@delon/util/array'; import { isEmpty } from '@delon/util/browser'; @Component({ selector: 'app-task-form', standalone: true, template: ` <form nz-form (ngSubmit)="handleSubmit()"> <!-- form fields --> <button nz-button [disabled]="hasEmptyRequired()"> 提交 </button> </form> ` }) export class TaskFormComponent { // Default form values private defaults = { priority: 'medium', status: 'pending', assignee: null, tags: [] }; // Form data with defaults formData = signal(deepCopy(this.defaults)); // Original task (for editing) originalTask = signal<Task | null>(null); // Load task for editing loadTask(task: Task): void { // Merge task data with defaults const merged = deepMerge(this.defaults, task); this.formData.set(merged); this.originalTask.set(deepCopy(task)); } // Check if required fields are empty hasEmptyRequired(): boolean { const data = this.formData(); return isEmpty(data.title) || isEmpty(data.assignee); } // Check if form has changes hasChanges(): boolean { const original = this.originalTask(); if (!original) return true; return !isEqual(original, this.formData()); } handleSubmit(): void { if (!this.hasEmptyRequired()) { // Create clean copy for submission const submitData = deepCopy(this.formData()); // Submit... } } } ``` ## Best Practices ### 1. Use Utilities for Immutability ✅ **DO**: ```typescript const taskCopy = deepCopy(task); taskCopy.status = 'completed'; this.tasks.update(tasks => [...tasks, taskCopy]); ``` ❌ **DON'T**: ```typescript task.status = 'completed'; this.tasks.update(tasks => [...tasks, task]); // Mutates original ``` ### 2. Leverage Computed Signals with Utilities ✅ **DO**: ```typescript groupedTasks = computed(() => groupBy(this.tasks(), 'status')); sortedTasks = computed(() => orderBy(this.tasks(), ['priority'], ['asc'])); ``` ### 3. Use Type-Safe Utilities ✅ **DO**: ```typescript import { deepCopy } from '@delon/util/array'; const copy: Task = deepCopy<Task>(originalTask); ``` ## Performance Considerations 1. **deepCopy**: Expensive for large objects - use sparingly 2. **groupBy/orderBy**: Wrap in computed() to avoid recalculation 3. **getTimeDistance**: Cache results if used frequently 4. **copy**: Async operation - handle loading states ## Integration Checklist - [ ] Install @delon/[email protected] - [ ] Import specific utilities (tree-shaking friendly) - [ ] Use with Angular Signals for reactivity - [ ] Add TypeScript generics for type safety - [ ] Handle async operations (copy) - [ ] Test edge cases (null, undefined, empty) ## Cross-References - **angular-component** - Signals integration - **delon-form** - Form utilities for validation - **firebase-repository** - deepCopy for state management --- **Version**: 1.0 **Created**: 2025-12-25 **Maintainer**: ng-events(GigHub) Development Team
Name Size