delon-util
@delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system.
Best use case
delon-util is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. @delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system.
@delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system.
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "delon-util" skill to help with this workflow task. Context: @delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system.
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/delon-util/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How delon-util Compares
| Feature / Agent | delon-util | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
@delon/util skill - Utility functions library for array, string, date, number manipulation. For ng-events construction site progress tracking system.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# @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/util@20.1.0
## 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/util@20.1.0
- [ ] 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 TeamRelated Skills
delon-form-dynamic-schema-forms
Create dynamic schema-based forms using @delon/form (SF component). Use this skill when building complex forms with validation, conditional rendering, async data loading, custom widgets, and multi-step workflows. Ensures forms follow JSON Schema standards, integrate with Angular reactive forms, support internationalization, and maintain consistent validation patterns across the application.
delon-chart
@delon/chart skill - G2Plot enterprise charting components with @delon/chart. For ng-events construction site progress tracking system.
delon-cache-caching-strategies
Implement caching strategies using @delon/cache. Use this skill when adding memory cache, LocalStorage cache, SessionStorage cache, or cache interceptors for HTTP requests. Supports TTL-based expiration, cache invalidation, cache grouping, and persistent storage. Optimizes performance by reducing redundant API calls and database queries.
delon-auth-authentication-authorization
Implement authentication and authorization using @delon/auth. Use this skill when adding login/logout flows, JWT token management, role-based access control (RBAC), route guards, HTTP interceptors, and session management. Integrates with Firebase Auth and custom permission systems. Ensures secure token storage, automatic token refresh, and consistent authorization checks across components and services.
delon-acl
@delon/acl skill - Access Control List for role-based permissions and UI element visibility. For ng-events construction site progress tracking system.
writing-utils
Use this skill when you need to write utility functions for the Next.js app
azure-quotas
Check/manage Azure quotas and usage across providers. For deployment planning, capacity validation, region selection. WHEN: "check quotas", "service limits", "current usage", "request quota increase", "quota exceeded", "validate capacity", "regional availability", "provisioning limits", "vCPU limit", "how many vCPUs available in my subscription".
raindrop-io
Manage Raindrop.io bookmarks with AI assistance. Save and organize bookmarks, search your collection, manage reading lists, and organize research materials. Use when working with bookmarks, web research, reading lists, or when user mentions Raindrop.io.
zlibrary-to-notebooklm
自动从 Z-Library 下载书籍并上传到 Google NotebookLM。支持 PDF/EPUB 格式,自动转换,一键创建知识库。
discover-skills
当你发现当前可用的技能都不够合适(或用户明确要求你寻找技能)时使用。本技能会基于任务目标和约束,给出一份精简的候选技能清单,帮助你选出最适配当前任务的技能。
web-performance-seo
Fix PageSpeed Insights/Lighthouse accessibility "!" errors caused by contrast audit failures (CSS filters, OKLCH/OKLAB, low opacity, gradient text, image backgrounds). Use for accessibility-driven SEO/performance debugging and remediation.
project-to-obsidian
将代码项目转换为 Obsidian 知识库。当用户提到 obsidian、项目文档、知识库、分析项目、转换项目 时激活。 【激活后必须执行】: 1. 先完整阅读本 SKILL.md 文件 2. 理解 AI 写入规则(默认到 00_Inbox/AI/、追加式、统一 Schema) 3. 执行 STEP 0: 使用 AskUserQuestion 询问用户确认 4. 用户确认后才开始 STEP 1 项目扫描 5. 严格按 STEP 0 → 1 → 2 → 3 → 4 顺序执行 【禁止行为】: - 禁止不读 SKILL.md 就开始分析项目 - 禁止跳过 STEP 0 用户确认 - 禁止直接在 30_Resources 创建(先到 00_Inbox/AI/) - 禁止自作主张决定输出位置