@idds/react 1.6.19 → 1.6.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +444 -0
- package/dist/index.cjs.js +2 -2
- package/dist/index.css +1 -1
- package/dist/index.es.js +950 -949
- package/dist/types/components/Modal.d.ts +3 -1
- package/dist/types/components/Modal.d.ts.map +1 -1
- package/package.json +6 -4
package/AGENT.md
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
# INA Digital Design System (IDDS) - React Comprehensive Agent Manual
|
|
2
|
+
|
|
3
|
+
This manual provides complete documentation for AI Coding Agents (such as GitHub Copilot, Cursor, Claude, Gemini) and human developers implementing `@idds/react` components. It outlines every available component, its complete set of React props, allowed parameter values, and clear usage patterns.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core Setup & Global Integration
|
|
8
|
+
|
|
9
|
+
### 1. Stylesheet Registration
|
|
10
|
+
The application MUST import the global stylesheet once at the application's top-level entry file (e.g., `main.tsx`, `App.tsx`, or `layout.tsx`):
|
|
11
|
+
```tsx
|
|
12
|
+
import '@idds/react/index.css';
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Component Import Rules
|
|
16
|
+
Always import components using standard named imports directly from the package root:
|
|
17
|
+
```tsx
|
|
18
|
+
import { Button, TextField, Modal, SelectDropdown } from '@idds/react';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Exhaustive Component Reference
|
|
24
|
+
|
|
25
|
+
### 1. Layout, Indicators & Generic Containers
|
|
26
|
+
|
|
27
|
+
#### `Button`
|
|
28
|
+
Trigger component supporting leading/trailing slots and multiple interaction hierarchies.
|
|
29
|
+
- **Props**:
|
|
30
|
+
- `hierarchy`: `'primary' | 'secondary' | 'tertiary' | 'link' | 'custom'` (Default: `'primary'`)
|
|
31
|
+
- `size`: `'2xl' | 'xl' | 'lg' | 'md' | 'sm'` (Default: `'md'`)
|
|
32
|
+
- `prefixIcon`: `ReactNode` (Optional leading icon)
|
|
33
|
+
- `suffixIcon`: `ReactNode` (Optional trailing icon)
|
|
34
|
+
- `disabled`: `boolean` (Default: `false`)
|
|
35
|
+
- `className`: `string`
|
|
36
|
+
- Inherits standard `ButtonHTMLAttributes<HTMLButtonElement>` (`onClick`, `type`, etc.)
|
|
37
|
+
- **Usage**:
|
|
38
|
+
```tsx
|
|
39
|
+
<Button hierarchy="primary" size="lg" onClick={() => handleSubmit()}>
|
|
40
|
+
Simpan Data
|
|
41
|
+
</Button>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### `ButtonGroup`
|
|
45
|
+
Groups multiple consecutive buttons into a unified border-radius strip.
|
|
46
|
+
- **Props**:
|
|
47
|
+
- `children`: `ReactNode` containing `<Button>` instances.
|
|
48
|
+
- `className`: `string`
|
|
49
|
+
- **Usage**:
|
|
50
|
+
```tsx
|
|
51
|
+
<ButtonGroup>
|
|
52
|
+
<Button hierarchy="secondary">Kiri</Button>
|
|
53
|
+
<Button hierarchy="secondary">Tengah</Button>
|
|
54
|
+
<Button hierarchy="primary">Kanan</Button>
|
|
55
|
+
</ButtonGroup>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### `Card`
|
|
59
|
+
Standardized container structure with consistent surface shadow and background layout.
|
|
60
|
+
- **Props**:
|
|
61
|
+
- `children`: `ReactNode`
|
|
62
|
+
- `className`: `string`
|
|
63
|
+
- `onClick`: `() => void`
|
|
64
|
+
- **Usage**:
|
|
65
|
+
```tsx
|
|
66
|
+
<Card className="p-4 border border-stroke-primary">
|
|
67
|
+
<h3>Judul Kartu</h3>
|
|
68
|
+
</Card>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### `CardPlain`
|
|
72
|
+
Minimalist unstyled semantic container wrapper.
|
|
73
|
+
- **Props**: `children`: `ReactNode`, `className`: `string`
|
|
74
|
+
|
|
75
|
+
#### `Divider`
|
|
76
|
+
Horizontal or vertical semantic line break separator.
|
|
77
|
+
- **Props**:
|
|
78
|
+
- `orientation`: `'horizontal' | 'vertical'` (Default: `'horizontal'`)
|
|
79
|
+
- `className`: `string`
|
|
80
|
+
|
|
81
|
+
#### `Skeleton`
|
|
82
|
+
Placeholder state element shown during loading pipelines.
|
|
83
|
+
- **Props**:
|
|
84
|
+
- `variant`: `'circular' | 'rectangular' | 'rounded'` (Default: `'rounded'`)
|
|
85
|
+
- `width`: `string | number`
|
|
86
|
+
- `height`: `string | number`
|
|
87
|
+
- `className`: `string`
|
|
88
|
+
- **Usage**:
|
|
89
|
+
```tsx
|
|
90
|
+
<Skeleton variant="rounded" height={40} width="100%" />
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### `Spinner`
|
|
94
|
+
Indeterminate circular graphical loading indicator.
|
|
95
|
+
- **Props**:
|
|
96
|
+
- `size`: `'sm' | 'md' | 'lg'` (Default: `'md'`)
|
|
97
|
+
- `color`: `string` (Optional custom CSS color override)
|
|
98
|
+
- `className`: `string`
|
|
99
|
+
|
|
100
|
+
#### `Avatar`
|
|
101
|
+
Displays profile thumbnail representation.
|
|
102
|
+
- **Props**:
|
|
103
|
+
- `src`: `string` (Image URL)
|
|
104
|
+
- `alt`: `string`
|
|
105
|
+
- `size`: `'sm' | 'md' | 'lg' | 'xl'` (Default: `'md'`)
|
|
106
|
+
- `fallbackText`: `string` (Initials shown if image fails/empty)
|
|
107
|
+
- **Usage**:
|
|
108
|
+
```tsx
|
|
109
|
+
<Avatar src="/path/img.png" fallbackText="JD" size="lg" />
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### `Badge`
|
|
113
|
+
Contextual status tag indicator.
|
|
114
|
+
- **Props**:
|
|
115
|
+
- `text`: `string | ReactNode`
|
|
116
|
+
- `variant`: `'success' | 'danger' | 'warning' | 'info' | 'neutral'` (Default: `'neutral'`)
|
|
117
|
+
- `type`: `'solid' | 'soft' | 'outline'` (Default: `'soft'`)
|
|
118
|
+
- `icon`: `ReactNode` (Optional icon placement)
|
|
119
|
+
- `className`: `string`
|
|
120
|
+
- **Usage**:
|
|
121
|
+
```tsx
|
|
122
|
+
<Badge text="Selesai" variant="success" type="solid" />
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### `CircleProgressBar`
|
|
126
|
+
Radial circular progression tracking interface.
|
|
127
|
+
- **Props**:
|
|
128
|
+
- `progress`: `number` (Percentage 0 to 100)
|
|
129
|
+
- `size`: `number` (Pixel radius)
|
|
130
|
+
- `strokeWidth`: `number`
|
|
131
|
+
- `showLabel`: `boolean` (Default: `true`)
|
|
132
|
+
|
|
133
|
+
#### `ProgressBar` / `LinearProgressIndicator` / `TableProgressBar`
|
|
134
|
+
Horizontal bar progress displays.
|
|
135
|
+
- **Props**:
|
|
136
|
+
- `progress`: `number` (0 to 100)
|
|
137
|
+
- `status`: `'default' | 'success' | 'error'`
|
|
138
|
+
- `className`: `string`
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### 2. Form Inputs (Controlled Pattern)
|
|
143
|
+
|
|
144
|
+
#### `TextField`
|
|
145
|
+
Standard robust input supporting debounce and direct clear logic.
|
|
146
|
+
- **Props**:
|
|
147
|
+
- `value`: `string` (Required controlled binding)
|
|
148
|
+
- `onChange`: `(val: string) => void`
|
|
149
|
+
- `onInput`: `(event: ChangeEvent<HTMLInputElement>) => void`
|
|
150
|
+
- `debounce`: `number` (Delay ms. Default: `0`)
|
|
151
|
+
- `onChangeDebounced`: `(val: string) => void`
|
|
152
|
+
- `label`: `ReactNode`
|
|
153
|
+
- `placeholder`: `string`
|
|
154
|
+
- `helperText`: `ReactNode`
|
|
155
|
+
- `errorMessage`: `string`
|
|
156
|
+
- `status`: `'neutral' | 'error' | 'warning' | 'success'` (Default: `'neutral'`)
|
|
157
|
+
- `statusMessage`: `ReactNode` (Overrides helperText based on state)
|
|
158
|
+
- `size`: `'sm' | 'md' | 'lg'` (Default: `'md'`)
|
|
159
|
+
- `maxLength`: `number`
|
|
160
|
+
- `showCharCount`: `boolean` (Default: `false`)
|
|
161
|
+
- `showClearButton`: `boolean` (Default: `true`)
|
|
162
|
+
- `onClear`: `() => void` (Custom clear action trigger)
|
|
163
|
+
- `disabled`: `boolean`
|
|
164
|
+
- `securityConfig`: `SecurityConfig` object
|
|
165
|
+
- **Usage**:
|
|
166
|
+
```tsx
|
|
167
|
+
<TextField
|
|
168
|
+
label="Nama Lengkap"
|
|
169
|
+
value={name}
|
|
170
|
+
onChange={(val) => setName(val)}
|
|
171
|
+
status={error ? 'error' : 'neutral'}
|
|
172
|
+
statusMessage={error ? 'Nama wajib diisi' : undefined}
|
|
173
|
+
showClearButton
|
|
174
|
+
/>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### `TextArea`
|
|
178
|
+
Adjustable multi-line text input field.
|
|
179
|
+
- **Props**:
|
|
180
|
+
- `value`: `string`
|
|
181
|
+
- `onChange`: `(val: string) => void`
|
|
182
|
+
- `label`, `placeholder`, `helperText`: `ReactNode`
|
|
183
|
+
- `status`: `'neutral' | 'error' | 'warning' | 'success'`
|
|
184
|
+
- `rows`: `number` (Default: `4`)
|
|
185
|
+
- `maxLength`: `number`
|
|
186
|
+
- `showCharCount`: `boolean`
|
|
187
|
+
- `disabled`: `boolean`
|
|
188
|
+
|
|
189
|
+
#### `PasswordInput`
|
|
190
|
+
Input field embedding masked string views with instant reveal toggle.
|
|
191
|
+
- **Props**: Identical base pattern to `TextField` minus irrelevant multi-line scopes. Includes accessible visibility toggle button.
|
|
192
|
+
|
|
193
|
+
#### `InputSearch`
|
|
194
|
+
Search bar optimized for quick search entries and reset triggers.
|
|
195
|
+
- **Props**: Identical to `TextField`, rendering leading search glass graphic automatically.
|
|
196
|
+
|
|
197
|
+
#### `PhoneInput`
|
|
198
|
+
Structured field featuring international formatting and dial codes.
|
|
199
|
+
- **Props**:
|
|
200
|
+
- `value`: `string`
|
|
201
|
+
- `onChange`: `(val: string) => void`
|
|
202
|
+
- `defaultCountry`: `string` (e.g., `'ID'`)
|
|
203
|
+
- `disabled`: `boolean`
|
|
204
|
+
- Includes space/enter accessibility bindings on embedded clear controls.
|
|
205
|
+
|
|
206
|
+
#### `Checkbox`
|
|
207
|
+
Single option boolean toggler.
|
|
208
|
+
- **Props**:
|
|
209
|
+
- `checked`: `boolean`
|
|
210
|
+
- `onChange`: `(checked: boolean) => void`
|
|
211
|
+
- `label`: `ReactNode`
|
|
212
|
+
- `disabled`: `boolean`
|
|
213
|
+
- `indeterminate`: `boolean`
|
|
214
|
+
- **Usage**:
|
|
215
|
+
```tsx
|
|
216
|
+
<Checkbox checked={agree} onChange={(c) => setAgree(c)} label="Setuju syarat" />
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### `RadioInput`
|
|
220
|
+
Selection input targeting array groups.
|
|
221
|
+
- **Props**:
|
|
222
|
+
- `options`: `Array<{ label: string; value: string | number; disabled?: boolean }>`
|
|
223
|
+
- `value`: `string | number`
|
|
224
|
+
- `onChange`: `(val: string | number) => void`
|
|
225
|
+
- `orientation`: `'horizontal' | 'vertical'`
|
|
226
|
+
- `label`: `ReactNode`
|
|
227
|
+
- `disabled`: `boolean`
|
|
228
|
+
|
|
229
|
+
#### `Toggle`
|
|
230
|
+
Switch boolean state toggler.
|
|
231
|
+
- **Props**: `checked`: `boolean`, `onChange`: `(checked: boolean) => void`, `label`: `ReactNode`, `disabled`: `boolean`.
|
|
232
|
+
|
|
233
|
+
#### `OneTimePassword`
|
|
234
|
+
Multi-segmented input field grouping code entries securely.
|
|
235
|
+
- **Props**:
|
|
236
|
+
- `length`: `number` (Default: `6`)
|
|
237
|
+
- `value`: `string`
|
|
238
|
+
- `onChange`: `(val: string) => void`
|
|
239
|
+
- `onComplete`: `(val: string) => void`
|
|
240
|
+
- `disabled`: `boolean`
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### 3. Selection, Pickers & Uploading
|
|
245
|
+
|
|
246
|
+
#### `SelectDropdown`
|
|
247
|
+
Robust feature-rich dropdown layout encapsulating remote load/search.
|
|
248
|
+
- **Props**:
|
|
249
|
+
- `options`: `Array<{ label: string; value: any; disabled?: boolean }>`
|
|
250
|
+
- `selected`: `any | any[]`
|
|
251
|
+
- `onSelect`: `(selectedValue: any | any[], rawValue?: any) => void`
|
|
252
|
+
- `placeholder`: `string`
|
|
253
|
+
- `size`: `'sm' | 'md' | 'lg'`
|
|
254
|
+
- `multiple`: `boolean` (Default: `false`)
|
|
255
|
+
- `indicator`: `'check' | 'radio'`
|
|
256
|
+
- `width`: `number | string` (Default: `'100%'`)
|
|
257
|
+
- `panelWidth`, `panelHeight`: `number | string`
|
|
258
|
+
- `searchable`: `boolean` (Default: `true`)
|
|
259
|
+
- `onSearch`: `(term: string) => void`
|
|
260
|
+
- `hasMore`, `loading`: `boolean` (Infinite scrolling flags)
|
|
261
|
+
- `onLoadMore`: `(page: number) => void`
|
|
262
|
+
- `mandatorySelected`: `boolean` (Ensures at least one item remains locked/selected)
|
|
263
|
+
- **Usage**:
|
|
264
|
+
```tsx
|
|
265
|
+
<SelectDropdown
|
|
266
|
+
options={[{ label: 'Opsi 1', value: 1 }, { label: 'Opsi 2', value: 2 }]}
|
|
267
|
+
selected={selectedItem}
|
|
268
|
+
onSelect={(val) => setSelectedItem(val)}
|
|
269
|
+
mandatorySelected
|
|
270
|
+
/>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### `ActionDropdown` / `BasicDropdown`
|
|
274
|
+
Trigger buttons exhibiting contextual menu floating lists.
|
|
275
|
+
- **Props**:
|
|
276
|
+
- `items`: `Array<{ label: ReactNode; onClick: () => void; icon?: ReactNode; disabled?: boolean }>`
|
|
277
|
+
- `triggerLabel`: `ReactNode`
|
|
278
|
+
|
|
279
|
+
#### `Chip`
|
|
280
|
+
Tags optimized for multi-select context filters.
|
|
281
|
+
- **Props**:
|
|
282
|
+
- `label`: `string`
|
|
283
|
+
- `selected`: `boolean`
|
|
284
|
+
- `onClick`: `() => void`
|
|
285
|
+
- `onRemove`: `() => void`
|
|
286
|
+
- `multiple`: `boolean`
|
|
287
|
+
- `disabled`: `boolean`
|
|
288
|
+
- Supports keyboard roving focus and deselect actions.
|
|
289
|
+
|
|
290
|
+
#### `MultipleChoiceGrid`
|
|
291
|
+
Grid map arrangement wrapper for multi-option mapping.
|
|
292
|
+
- **Props**: `options`: `Array`, `selectedValues`: `Array`, `onChange`: `(arr) => void`
|
|
293
|
+
|
|
294
|
+
#### `DatePicker`
|
|
295
|
+
Interactive date selector supporting fluid input layers.
|
|
296
|
+
- **Props**:
|
|
297
|
+
- `mode`: `'single' | 'range' | 'multiple'` (Default: `'single'`)
|
|
298
|
+
- `selected`: `Date | [Date | null, Date | null] | Date[] | null`
|
|
299
|
+
- `onChange`: `(date: any) => void`
|
|
300
|
+
- `placeholder`: `string`
|
|
301
|
+
- `disabled`: `boolean`
|
|
302
|
+
- `minDate`, `maxDate`: `Date`
|
|
303
|
+
- **Usage**:
|
|
304
|
+
```tsx
|
|
305
|
+
<DatePicker selected={date} onChange={(d) => setDate(d)} mode="single" />
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
#### `MonthPicker` / `YearPicker`
|
|
309
|
+
Granular rapid timeframe scoping drillers.
|
|
310
|
+
- **Props**: `selected`: `number | string`, `onChange`: `(val) => void`, `minYear`/`maxYear`
|
|
311
|
+
|
|
312
|
+
#### `TimePicker`
|
|
313
|
+
Time tracking inputs.
|
|
314
|
+
- **Props**:
|
|
315
|
+
- `value`: `string` (Format: `'HH:mm'` or `'HH:mm:ss'`)
|
|
316
|
+
- `onChange`: `(val: string) => void`
|
|
317
|
+
- Fully embeds auto-formatting logic (injecting `:` automatically during manual text entries). Includes accessible Space/Enter trigger handling on reset icons.
|
|
318
|
+
|
|
319
|
+
#### `FileUpload` / `SingleFileUpload`
|
|
320
|
+
Drag-and-drop structural media file upload blocks.
|
|
321
|
+
- **Props**:
|
|
322
|
+
- `onFilesSelected`: `(files: File[]) => void` (or `File` for single)
|
|
323
|
+
- `maxSize`: `number` (Bytes limit)
|
|
324
|
+
- `acceptedFormats`: `string` (e.g., `'.pdf, .jpg, .png'`)
|
|
325
|
+
- `disabled`: `boolean`
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
### 4. Navigation, View Structures & Feedback
|
|
330
|
+
|
|
331
|
+
#### `Accordion` / `AccordionGroup` / `AccordionCard`
|
|
332
|
+
Expandable structural stack containers.
|
|
333
|
+
- **Props**:
|
|
334
|
+
- `title`: `ReactNode`
|
|
335
|
+
- `children`: `ReactNode`
|
|
336
|
+
- `defaultExpanded`: `boolean`
|
|
337
|
+
- Fully navigable using Keyboard Arrow keys.
|
|
338
|
+
|
|
339
|
+
#### `Breadcrumb`
|
|
340
|
+
Path trailing step indicator interfaces.
|
|
341
|
+
- **Props**:
|
|
342
|
+
- `items`: `Array<{ label: string; href?: string; onClick?: () => void }>`
|
|
343
|
+
- **Usage**:
|
|
344
|
+
```tsx
|
|
345
|
+
<Breadcrumb
|
|
346
|
+
items={[
|
|
347
|
+
{ label: 'Beranda', onClick: () => navigate('/') },
|
|
348
|
+
{ label: 'Formulir' }
|
|
349
|
+
]}
|
|
350
|
+
/>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
#### `TabHorizontal` / `TabVertical`
|
|
354
|
+
Tab structures managing context sub-views smoothly.
|
|
355
|
+
- **Props**:
|
|
356
|
+
- `tabs`: `Array<{ id: string; label: ReactNode; content?: ReactNode; disabled?: boolean }>`
|
|
357
|
+
- `activeTab`: `string`
|
|
358
|
+
- `onChange`: `(tabId: string) => void`
|
|
359
|
+
|
|
360
|
+
#### `Pagination`
|
|
361
|
+
Data listing page controller.
|
|
362
|
+
- **Props**:
|
|
363
|
+
- `currentPage`: `number`
|
|
364
|
+
- `totalPages`: `number`
|
|
365
|
+
- `onPageChange`: `(page: number) => void`
|
|
366
|
+
|
|
367
|
+
#### `Stepper`
|
|
368
|
+
Workflow progress milestone tracks.
|
|
369
|
+
- **Props**: `steps`: `Array<{ label: string; description?: string }>`, `activeStep`: `number`
|
|
370
|
+
|
|
371
|
+
#### `Table` / `FieldInputTable`
|
|
372
|
+
High fidelity complex layout grids supporting responsive dimensions.
|
|
373
|
+
- **Props**:
|
|
374
|
+
- `columns`: `Array<{ header: ReactNode; accessor: string; width?: string | number; className?: string }>`
|
|
375
|
+
- `data`: `Array<Record<string, any>>`
|
|
376
|
+
|
|
377
|
+
#### `Modal`
|
|
378
|
+
Portal accessible overlay interface containing automated flex overflow features.
|
|
379
|
+
- **Props**:
|
|
380
|
+
- `open`: `boolean`
|
|
381
|
+
- `onClose`: `() => void`
|
|
382
|
+
- `title`: `ReactNode`
|
|
383
|
+
- `children`: `ReactNode`
|
|
384
|
+
- `size`: `'sm' | 'md' | 'lg' | 'xl' | 'full' | ''`
|
|
385
|
+
- `hideHeader`: `boolean` (Default: `false`)
|
|
386
|
+
- `closeOnBackdrop`: `boolean` (Default: `true`)
|
|
387
|
+
- **Usage**:
|
|
388
|
+
```tsx
|
|
389
|
+
<Modal open={isOpen} onClose={() => setIsOpen(false)} title="Peringatan" size="md">
|
|
390
|
+
<p>Apakah Anda yakin ingin menghapus data ini?</p>
|
|
391
|
+
</Modal>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
#### `Drawer` / `BottomSheet`
|
|
395
|
+
Side and bottom sliding dynamic responsive panels.
|
|
396
|
+
- **Props**: `open`: `boolean`, `onClose`: `() => void`, `placement`: `'left' | 'right'` (Drawer)
|
|
397
|
+
|
|
398
|
+
#### `Collapse`
|
|
399
|
+
Smooth transition container wrapper hiding sub-DOM nodes.
|
|
400
|
+
- **Props**: `isOpen`: `boolean`, `children`: `ReactNode`
|
|
401
|
+
|
|
402
|
+
#### `Tooltip`
|
|
403
|
+
Floating informational cues.
|
|
404
|
+
- **Props**:
|
|
405
|
+
- `content`: `ReactNode`
|
|
406
|
+
- `children`: `ReactElement`
|
|
407
|
+
- `placement`: Supports 12 distinct positions (`'top-start'`, `'top'`, `'top-end'`, `'bottom-start'`, `'bottom'`, `'bottom-end'`, `'left-start'`, `'left'`, `'left-end'`, `'right-start'`, `'right'`, `'right-end'`)
|
|
408
|
+
|
|
409
|
+
#### `Toast` / `ToastProvider`
|
|
410
|
+
Contextual non-blocking messaging API.
|
|
411
|
+
- **Usage**:
|
|
412
|
+
Ensure application wraps top layers inside `<ToastProvider>`. Trigger messages directly using the internal context hook:
|
|
413
|
+
```tsx
|
|
414
|
+
import { useToast } from '@idds/react';
|
|
415
|
+
|
|
416
|
+
function Child() {
|
|
417
|
+
const { toast } = useToast();
|
|
418
|
+
return (
|
|
419
|
+
<button onClick={() => toast({ state: 'positive', title: 'Sukses', description: 'Tersimpan' })}>
|
|
420
|
+
Kirim
|
|
421
|
+
</button>
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### `Alert`
|
|
427
|
+
Static informative view strip.
|
|
428
|
+
- **Props**: `state`: `'info' | 'positive' | 'warning' | 'destructive'`, `title`: `string`, `description`: `ReactNode`
|
|
429
|
+
|
|
430
|
+
#### `ThemeToggle`
|
|
431
|
+
Out-of-the-box UI widget switching global light/dark layouts automatically.
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Global Theme Commands
|
|
436
|
+
IDDS reads the root HTML document `[data-theme]` parameter securely.
|
|
437
|
+
- Access available runtime toggle commands:
|
|
438
|
+
```typescript
|
|
439
|
+
import { setThemeMode, getThemeMode, toggleThemeMode } from '@idds/react';
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
## AI Implementor Guidelines
|
|
443
|
+
1. **Rely strictly on provided design props** (e.g., `status="error"`, `variant="danger"`). Do not attempt to inject custom CSS classes modifying border frames or colors manually.
|
|
444
|
+
2. **Accessible inputs**: Prefer setting native form helpers via the `errorMessage` property directly to guarantee proper ARIA screen reader link indices.
|