0
# UI Components
1
2
The @strapi/helper-plugin package provides a comprehensive collection of 29 UI components designed specifically for building Strapi plugin interfaces. These components offer consistent styling, accessibility features, and seamless integration with Strapi's design system.
3
4
## Core Components
5
6
Essential components for error handling, permissions, and content layout.
7
8
```typescript { .api }
9
// Error display component
10
interface AnErrorOccurredProps {
11
children?: React.ReactNode;
12
}
13
function AnErrorOccurred(props: AnErrorOccurredProps): JSX.Element;
14
15
// Permission-based page access control
16
interface CheckPagePermissionsProps {
17
permissions: Array<{ action: string; subject: string }>;
18
children: React.ReactNode;
19
fallback?: React.ComponentType;
20
}
21
function CheckPagePermissions(props: CheckPagePermissionsProps): JSX.Element;
22
23
// Permission checking wrapper
24
interface CheckPermissionsProps {
25
children: React.ReactNode;
26
permissions?: Array<{ action: string; subject: string }>;
27
}
28
function CheckPermissions(props: CheckPermissionsProps): JSX.Element;
29
30
// Modal confirmation dialog
31
interface ConfirmDialogProps {
32
isOpen: boolean;
33
onToggleDialog: () => void;
34
title?: TranslationMessage;
35
bodyText?: TranslationMessage;
36
onConfirm?: () => void;
37
}
38
function ConfirmDialog(props: ConfirmDialogProps): JSX.Element;
39
40
// Content container component
41
interface ContentBoxProps {
42
children: React.ReactNode;
43
title?: string;
44
subtitle?: string;
45
icon?: React.ReactNode;
46
titleEllipsis?: boolean;
47
}
48
function ContentBox(props: ContentBoxProps): JSX.Element;
49
```
50
51
**Usage Examples:**
52
53
```typescript
54
// Permission-based rendering
55
<CheckPermissions permissions={[{ action: 'read', subject: 'plugin::my-plugin.entity' }]}>
56
<MyProtectedComponent />
57
</CheckPermissions>
58
59
// Confirmation dialog
60
<ConfirmDialog
61
isOpen={showDialog}
62
onToggleDialog={setShowDialog}
63
title="Delete Entry"
64
bodyText="Are you sure you want to delete this entry?"
65
onConfirm={handleDelete}
66
isConfirmButtonLoading={isDeleting}
67
/>
68
```
69
70
## Form Components
71
72
Components for building complex forms with validation and accessibility support.
73
74
```typescript { .api }
75
// Date and time picker component
76
interface DateTimePickerProps {
77
value?: string | Date;
78
onChange: (value: string | Date | null) => void;
79
disabled?: boolean;
80
error?: string | TranslationMessage;
81
description?: string | TranslationMessage;
82
intlLabel: TranslationMessage;
83
name: string;
84
step?: number;
85
required?: boolean;
86
}
87
function DateTimePicker(props: DateTimePickerProps): JSX.Element;
88
89
// Formik form wrapper (deprecated - use Formik directly)
90
interface FormProps extends Omit<FormikFormProps, 'noValidate'> {
91
children: React.ReactNode;
92
}
93
function Form(props: FormProps): JSX.Element;
94
95
// Generic input field with type support
96
interface GenericInputProps {
97
type: string;
98
name: string;
99
value?: any;
100
onChange?: (event: { target: { name: string; value: any; type: string } }) => void;
101
error?: string | TranslationMessage;
102
description?: string | TranslationMessage;
103
disabled?: boolean;
104
intlLabel?: TranslationMessage;
105
placeholder?: string | TranslationMessage;
106
required?: boolean;
107
step?: number;
108
max?: number;
109
min?: number;
110
attribute?: any;
111
}
112
function GenericInput(props: GenericInputProps): JSX.Element;
113
114
// Restricted/disabled input field
115
interface NotAllowedInputProps {
116
name: string;
117
intlLabel: TranslationMessage;
118
description?: TranslationMessage;
119
}
120
function NotAllowedInput(props: NotAllowedInputProps): JSX.Element;
121
122
// React-select wrapper component
123
interface ReactSelectProps {
124
value?: any;
125
options: Array<{ label: string; value: any }>;
126
onChange: (value: any) => void;
127
isMulti?: boolean;
128
placeholder?: string;
129
isDisabled?: boolean;
130
isClearable?: boolean;
131
isSearchable?: boolean;
132
name?: string;
133
}
134
function ReactSelect(props: ReactSelectProps): JSX.Element;
135
```
136
137
**Usage Examples:**
138
139
```typescript
140
// Generic input field
141
<GenericInput
142
type="text"
143
name="title"
144
value={formData.title}
145
onChange={handleInputChange}
146
intlLabel={{ id: 'form.title.label', defaultMessage: 'Title' }}
147
required
148
/>
149
150
// Date time picker
151
<DateTimePicker
152
name="publishedAt"
153
value={publishDate}
154
onChange={setPublishDate}
155
intlLabel={{ id: 'form.publishDate.label', defaultMessage: 'Publish Date' }}
156
/>
157
```
158
159
## Table Components
160
161
Components for displaying and managing tabular data with sorting, pagination, and bulk actions.
162
163
```typescript { .api }
164
// Advanced table with selection and actions
165
interface TableProps<TRows extends { id: Entity.ID } = { id: Entity.ID }> {
166
children?: React.ReactNode;
167
contentType: string;
168
headers?: Array<TableHeader>;
169
rows?: Array<TRows>;
170
isLoading?: boolean;
171
withBulkActions?: boolean;
172
withMainAction?: boolean;
173
onConfirmDeleteAll?: (ids: Array<TRows['id']>) => Promise<void>;
174
onConfirmDelete?: (id: TRows['id']) => Promise<void>;
175
renderBulkActionsBar?: (props: {
176
selectedEntries: Array<string | number>;
177
clearSelectedEntries: () => void;
178
}) => React.ReactNode;
179
footer?: React.ReactNode;
180
action?: React.ReactNode;
181
}
182
function DynamicTable<TRows extends { id: Entity.ID }>(props: TableProps<TRows>): JSX.Element;
183
184
// Basic table component
185
interface BasicTableProps {
186
headers: Array<{ name: string; label: string }>;
187
rows: Array<Record<string, any>>;
188
className?: string;
189
}
190
function Table(props: BasicTableProps): JSX.Element;
191
192
// Empty table body placeholder
193
interface EmptyBodyTableProps {
194
colSpan: number;
195
content?: TranslationMessage;
196
isLoading?: boolean;
197
action?: React.ReactNode;
198
}
199
function EmptyBodyTable(props: EmptyBodyTableProps): JSX.Element;
200
201
// Table header interface
202
interface TableHeader {
203
name: string;
204
metadatas: {
205
sortable: boolean;
206
label: string;
207
mainField?: { name: string };
208
};
209
fieldSchema?: { type: string };
210
}
211
```
212
213
**Usage Examples:**
214
215
```typescript
216
// Dynamic table with bulk actions
217
<DynamicTable
218
contentType="articles"
219
headers={[
220
{ name: 'title', metadatas: { label: 'Title', sortable: true } },
221
{ name: 'status', metadatas: { label: 'Status', sortable: false } }
222
]}
223
rows={articles}
224
withBulkActions
225
withMainAction
226
onConfirmDelete={handleDelete}
227
onConfirmDeleteAll={handleBulkDelete}
228
/>
229
```
230
231
## URL Query Components
232
233
Components that synchronize their state with URL parameters for deep linking and browser navigation.
234
235
```typescript { .api }
236
// URL-synced filter list interface
237
interface FilterListURLQueryProps {
238
filtersSchema: Array<FilterData>;
239
displayedFilters: Array<{
240
name: string;
241
filter: Filter;
242
operator: string;
243
value: string;
244
}>;
245
}
246
function FilterListURLQuery(props: FilterListURLQueryProps): JSX.Element;
247
248
// Popover-based filter interface with URL sync
249
interface FilterPopoverURLQueryProps {
250
displayedFilters: Array<FilterData>;
251
isVisible: boolean;
252
onToggle: () => void;
253
source?: string;
254
slug?: string;
255
}
256
function FilterPopoverURLQuery(props: FilterPopoverURLQueryProps): JSX.Element;
257
258
// URL-synced page size selector
259
interface PageSizeURLQueryProps {
260
trackedEvent?: string;
261
}
262
function PageSizeURLQuery(props: PageSizeURLQueryProps): JSX.Element;
263
264
// URL-synced pagination component
265
interface PaginationURLQueryProps {
266
pagination: {
267
page: number;
268
pageCount: number;
269
pageSize: number;
270
total: number;
271
};
272
}
273
function PaginationURLQuery(props: PaginationURLQueryProps): JSX.Element;
274
275
// URL-synced search input
276
interface SearchURLQueryProps {
277
label: string;
278
placeholder?: string;
279
trackedEvent?: string;
280
}
281
function SearchURLQuery(props: SearchURLQueryProps): JSX.Element;
282
```
283
284
**Usage Examples:**
285
286
```typescript
287
// Search with URL synchronization
288
<SearchURLQuery
289
label="Search articles"
290
placeholder="Search by title, content..."
291
trackedEvent="didSearch"
292
/>
293
294
// Pagination with URL state
295
<PaginationURLQuery
296
pagination={{
297
page: 1,
298
pageCount: 10,
299
pageSize: 20,
300
total: 200
301
}}
302
/>
303
```
304
305
## Navigation & Layout
306
307
Components for navigation, links, and content organization.
308
309
```typescript { .api }
310
// Internal link component with router integration
311
interface LinkProps {
312
to: string;
313
children: React.ReactNode;
314
isExternal?: boolean;
315
onClick?: () => void;
316
}
317
function Link(props: LinkProps): JSX.Element;
318
319
// Button-styled link component
320
interface LinkButtonProps {
321
to: string;
322
children: React.ReactNode;
323
variant?: 'default' | 'primary' | 'secondary' | 'tertiary' | 'success' | 'danger';
324
disabled?: boolean;
325
size?: 'S' | 'M' | 'L';
326
startIcon?: React.ReactNode;
327
endIcon?: React.ReactNode;
328
}
329
function LinkButton(props: LinkButtonProps): JSX.Element;
330
331
// Plugin injection zone for extensibility
332
interface InjectionZoneProps {
333
area: string;
334
children?: React.ReactNode;
335
}
336
function InjectionZone(props: InjectionZoneProps): JSX.Element;
337
```
338
339
**Usage Examples:**
340
341
```typescript
342
// Router-integrated link
343
<Link to="/admin/plugins/my-plugin/settings">
344
Plugin Settings
345
</Link>
346
347
// Button-styled navigation
348
<LinkButton to="/admin/content-manager" variant="primary" startIcon={<Plus />}>
349
Create New Entry
350
</LinkButton>
351
```
352
353
## State & Status Components
354
355
Components for displaying loading states, empty states, and status information.
356
357
```typescript { .api }
358
// Empty state layout component
359
interface EmptyStateLayoutProps {
360
icon?: React.ReactNode;
361
content: React.ReactNode;
362
action?: React.ReactNode;
363
hasRadius?: boolean;
364
shadow?: string;
365
}
366
function EmptyStateLayout(props: EmptyStateLayoutProps): JSX.Element;
367
368
// Full-page loading indicator
369
function LoadingIndicatorPage(): JSX.Element;
370
371
// No content placeholder component
372
interface NoContentProps {
373
content?: React.ReactNode;
374
action?: React.ReactNode;
375
}
376
function NoContent(props: NoContentProps): JSX.Element;
377
378
// No media placeholder
379
function NoMedia(): JSX.Element;
380
381
// No permissions placeholder
382
function NoPermissions(): JSX.Element;
383
384
// Status indicator component
385
interface StatusProps {
386
variant: 'alternative' | 'danger' | 'neutral' | 'primary' | 'secondary' | 'success' | 'warning';
387
children: React.ReactNode;
388
size?: 'S' | 'M';
389
showBullet?: boolean;
390
}
391
function Status(props: StatusProps): JSX.Element;
392
```
393
394
**Usage Examples:**
395
396
```typescript
397
// Empty state with action
398
<EmptyStateLayout
399
icon={<Document />}
400
content="No articles found"
401
action={
402
<Button onClick={handleCreate}>
403
Create your first article
404
</Button>
405
}
406
/>
407
408
// Status indicator
409
<Status variant="success" showBullet>
410
Published
411
</Status>
412
```
413
414
## Utility Components
415
416
Specialized components for time display, page titles, and other utilities.
417
418
```typescript { .api }
419
// Relative time display component
420
interface RelativeTimeProps {
421
timestamp: string | Date;
422
customIntervals?: Array<{
423
unit: Intl.RelativeTimeFormatUnit;
424
threshold: number;
425
}>;
426
}
427
function RelativeTime(props: RelativeTimeProps): JSX.Element;
428
429
// Settings page title with Helmet integration
430
interface SettingsPageTitleProps {
431
name: string;
432
}
433
function SettingsPageTitle(props: SettingsPageTitleProps): JSX.Element;
434
```
435
436
**Usage Examples:**
437
438
```typescript
439
// Relative time display
440
<RelativeTime timestamp={article.createdAt} />
441
442
// Page title with SEO
443
<SettingsPageTitle name="Plugin Settings" />
444
```