0
# Utilities and Helpers
1
2
Utility functions for common tasks including form state building, URL handling, validation, data processing, and admin interface operations.
3
4
## Form and Data Utilities
5
6
### buildFormState
7
8
Construct form state from field schemas and data.
9
10
```typescript { .api }
11
function buildFormState(options: {
12
fieldSchema: FieldSchema[];
13
data?: Record<string, unknown>;
14
operation?: 'create' | 'update';
15
locale?: string;
16
id?: string | number;
17
}): FormState;
18
19
interface FormState {
20
[path: string]: {
21
value: unknown;
22
valid: boolean;
23
errorMessage?: string;
24
disableFormData?: boolean;
25
initialValue?: unknown;
26
};
27
}
28
29
interface FieldSchema {
30
name: string;
31
type: string;
32
required?: boolean;
33
defaultValue?: unknown;
34
validate?: (value: unknown, options: ValidateOptions) => string | true;
35
}
36
```
37
38
Usage example:
39
```typescript
40
import { buildFormState } from '@payloadcms/ui/shared';
41
42
function createDocumentForm(fieldConfig, initialData) {
43
const formState = buildFormState({
44
fieldSchema: fieldConfig,
45
data: initialData,
46
operation: 'create',
47
locale: 'en'
48
});
49
50
return formState;
51
}
52
```
53
54
### buildTableState
55
56
Construct table state configuration from collection data.
57
58
```typescript { .api }
59
function buildTableState(options: {
60
columns: Column[];
61
data: Record<string, unknown>[];
62
sortColumn?: string;
63
sortDirection?: 'asc' | 'desc';
64
}): TableState;
65
66
interface TableState {
67
columns: Column[];
68
data: Record<string, unknown>[];
69
sort: {
70
column?: string;
71
direction: 'asc' | 'desc';
72
};
73
}
74
```
75
76
### parseSearchParams
77
78
Parse URL search parameters into a structured object.
79
80
```typescript { .api }
81
function parseSearchParams(search: string): Record<string, unknown>;
82
```
83
84
Usage example:
85
```typescript
86
import { parseSearchParams } from '@payloadcms/ui';
87
88
function handleUrlParams() {
89
const params = parseSearchParams(window.location.search);
90
// Returns: { page: "2", limit: "25", where: {...} }
91
92
return params;
93
}
94
```
95
96
## URL and Navigation Utilities
97
98
### formatAdminURL
99
100
Format admin panel URLs with proper routing.
101
102
```typescript { .api }
103
function formatAdminURL(args: {
104
adminRoute: string;
105
path: string;
106
locale?: string;
107
}): string;
108
```
109
110
Usage example:
111
```typescript
112
import { formatAdminURL } from '@payloadcms/ui';
113
114
function getCollectionURL(slug: string) {
115
return formatAdminURL({
116
adminRoute: '/admin',
117
path: `/collections/${slug}`,
118
locale: 'en'
119
});
120
}
121
```
122
123
### Navigation Handlers
124
125
Functions for handling common navigation actions.
126
127
```typescript { .api }
128
function handleBackToDashboard(): void;
129
function handleGoBack(): void;
130
function handleTakeOver(args: {
131
id: string | number;
132
collectionSlug?: string;
133
globalSlug?: string;
134
}): Promise<void>;
135
```
136
137
### Navigation Item Utilities
138
139
```typescript { .api }
140
function groupNavItems(items: NavItem[]): GroupedNavItems;
141
142
interface NavItem {
143
label: string;
144
url: string;
145
group?: string;
146
active?: boolean;
147
}
148
149
interface GroupedNavItems {
150
[group: string]: NavItem[];
151
}
152
```
153
154
## Validation and Permissions
155
156
### hasSavePermission
157
158
Check if user has permission to save a document.
159
160
```typescript { .api }
161
function hasSavePermission(args: {
162
collectionSlug?: string;
163
globalSlug?: string;
164
operation: 'create' | 'update';
165
permissions?: SanitizedPermissions;
166
}): boolean;
167
```
168
169
### Permission Checking
170
171
```typescript { .api }
172
function isEditing(operation: string): boolean;
173
function isClientUserObject(user: unknown): user is ClientUser;
174
```
175
176
## Data Processing
177
178
### sanitizeID
179
180
Sanitize document ID for safe usage.
181
182
```typescript { .api }
183
function sanitizeID(id: unknown): string;
184
```
185
186
### Field Processing Utilities
187
188
```typescript { .api }
189
function reduceToSerializableFields(args: {
190
fields: FieldConfig[];
191
data: Record<string, unknown>;
192
}): Record<string, unknown>;
193
194
function filterFields(args: {
195
fields: FieldConfig[];
196
operation: 'create' | 'update' | 'read';
197
permissions?: Record<string, unknown>;
198
}): FieldConfig[];
199
200
function mergeFieldStyles(
201
baseStyles: Record<string, unknown>,
202
customStyles?: Record<string, unknown>
203
): Record<string, unknown>;
204
```
205
206
## Date and Formatting
207
208
### formatDate
209
210
Format dates for display in admin interface.
211
212
```typescript { .api }
213
function formatDate(args: {
214
date: Date | string;
215
pattern?: string;
216
locale?: string;
217
}): string;
218
```
219
220
Usage example:
221
```typescript
222
import { formatDate } from '@payloadcms/ui';
223
224
function DisplayDate({ date }) {
225
const formatted = formatDate({
226
date: date,
227
pattern: 'PPP',
228
locale: 'en-US'
229
});
230
231
return <span>{formatted}</span>;
232
}
233
```
234
235
### Document Title Formatting
236
237
```typescript { .api }
238
function formatDocTitle(args: {
239
data: Record<string, unknown>;
240
useAsTitle?: string;
241
fallback?: string;
242
}): string;
243
244
function formatTimeToNow(date: Date | string): string;
245
```
246
247
### Locale Utilities
248
249
```typescript { .api }
250
function findLocaleFromCode(
251
code: string,
252
locales: LocaleConfig[]
253
): LocaleConfig | undefined;
254
255
interface LocaleConfig {
256
label: string;
257
code: string;
258
}
259
```
260
261
## Table and Column Utilities
262
263
### getInitialColumns
264
265
Initialize table columns from configuration.
266
267
```typescript { .api }
268
function getInitialColumns(args: {
269
collectionConfig: CollectionConfig;
270
preferences?: ColumnPreferences;
271
defaultColumns?: string[];
272
}): Column[];
273
274
interface ColumnPreferences {
275
[field: string]: {
276
active: boolean;
277
width?: number;
278
};
279
}
280
```
281
282
## Server-Side Utilities (RSC)
283
284
Utilities available in the RSC (React Server Components) export for server-side rendering.
285
286
### getFolderResultsComponentAndData
287
288
Fetch folder data and component for server-side rendering.
289
290
```typescript { .api }
291
function getFolderResultsComponentAndData(args: {
292
collectionSlug: string;
293
folder?: string;
294
locale?: string;
295
where?: Record<string, unknown>;
296
limit?: number;
297
page?: number;
298
}): Promise<{
299
Component: React.ComponentType;
300
data: FolderResult;
301
}>;
302
303
interface FolderResult {
304
docs: Record<string, unknown>[];
305
folders: FolderConfig[];
306
totalDocs: number;
307
}
308
```
309
310
### renderFilters
311
312
Server-side filter rendering utility.
313
314
```typescript { .api }
315
function renderFilters(args: {
316
collectionConfig: CollectionConfig;
317
where?: Record<string, unknown>;
318
locale?: string;
319
}): React.ReactNode;
320
```
321
322
### renderTable
323
324
Server-side table rendering utility.
325
326
```typescript { .api }
327
function renderTable(args: {
328
data: Record<string, unknown>[];
329
columns: Column[];
330
collectionSlug: string;
331
}): React.ReactNode;
332
```
333
334
### copyDataFromLocaleHandler
335
336
Handle copying data between locales.
337
338
```typescript { .api }
339
function copyDataFromLocaleHandler(args: {
340
data: Record<string, unknown>;
341
fromLocale: string;
342
toLocale: string;
343
fields: FieldConfig[];
344
}): Record<string, unknown>;
345
```
346
347
## Request and API Utilities
348
349
### HTTP Request Utilities
350
351
```typescript { .api }
352
const requests: {
353
get: (url: string, options?: RequestOptions) => Promise<Response>;
354
post: (url: string, options?: RequestOptions) => Promise<Response>;
355
patch: (url: string, options?: RequestOptions) => Promise<Response>;
356
delete: (url: string, options?: RequestOptions) => Promise<Response>;
357
};
358
359
interface RequestOptions {
360
headers?: Record<string, string>;
361
body?: BodyInit;
362
signal?: AbortSignal;
363
}
364
```
365
366
## Utility Usage Examples
367
368
### Form State Management
369
370
```typescript
371
import { buildFormState, useForm } from '@payloadcms/ui';
372
373
function DynamicForm({ fieldConfig, initialData }) {
374
const formState = buildFormState({
375
fieldSchema: fieldConfig,
376
data: initialData,
377
operation: 'update'
378
});
379
380
const { submit, validate } = useForm();
381
382
const handleSubmit = async () => {
383
if (validate()) {
384
await submit();
385
}
386
};
387
388
return (
389
<form onSubmit={handleSubmit}>
390
{/* Form fields */}
391
</form>
392
);
393
}
394
```
395
396
### Permission-Based Rendering
397
398
```typescript
399
import { hasSavePermission, useAuth } from '@payloadcms/ui';
400
401
function DocumentActions({ collectionSlug }) {
402
const { permissions } = useAuth();
403
404
const canSave = hasSavePermission({
405
collectionSlug,
406
operation: 'update',
407
permissions
408
});
409
410
return (
411
<div>
412
{canSave && (
413
<Button type="submit">Save</Button>
414
)}
415
</div>
416
);
417
}
418
```
419
420
### URL Management
421
422
```typescript
423
import { formatAdminURL, parseSearchParams } from '@payloadcms/ui';
424
425
function NavigationHelper() {
426
const currentParams = parseSearchParams(window.location.search);
427
428
const getEditURL = (id: string) => {
429
return formatAdminURL({
430
adminRoute: '/admin',
431
path: `/collections/posts/${id}`
432
});
433
};
434
435
return {
436
currentParams,
437
getEditURL
438
};
439
}
440
```
441
442
### Date Display
443
444
```typescript
445
import { formatDate, formatTimeToNow } from '@payloadcms/ui';
446
447
function DateDisplay({ createdAt, updatedAt }) {
448
return (
449
<div>
450
<span>Created: {formatDate({ date: createdAt, pattern: 'PPP' })}</span>
451
<span>Updated: {formatTimeToNow(updatedAt)}</span>
452
</div>
453
);
454
}
455
```
456
457
## Types
458
459
```typescript { .api }
460
interface ValidateOptions {
461
data: Record<string, unknown>;
462
siblingData: Record<string, unknown>;
463
operation: 'create' | 'update';
464
id?: string | number;
465
}
466
467
interface Column {
468
accessor: string;
469
label: string;
470
active?: boolean;
471
width?: number;
472
}
473
474
interface CollectionConfig {
475
slug: string;
476
fields: FieldConfig[];
477
admin?: AdminConfig;
478
}
479
480
interface FieldConfig {
481
name: string;
482
type: string;
483
label?: string;
484
required?: boolean;
485
admin?: Record<string, unknown>;
486
}
487
488
interface SanitizedPermissions {
489
collections: Record<string, CollectionPermission>;
490
globals: Record<string, GlobalPermission>;
491
canAccessAdmin: boolean;
492
}
493
494
interface CollectionPermission {
495
create: boolean;
496
read: boolean;
497
update: boolean;
498
delete: boolean;
499
}
500
501
interface GlobalPermission {
502
read: boolean;
503
update: boolean;
504
}
505
506
interface ClientUser {
507
id: string;
508
email?: string;
509
[key: string]: unknown;
510
}
511
512
interface FolderConfig {
513
id: string;
514
name: string;
515
parent?: string;
516
}
517
```