@iress-oss/ids-components 6.0.0-alpha.31 → 6.0.0-alpha.33
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/.ai/guides/migration-guides-oui.md +574 -0
- package/.ai/guides/migration-guides-v6.md +576 -0
- package/.ai/guides/styling-props-accessibility.md +6 -0
- package/.ai/guides/styling-props-reference.md +33 -0
- package/.ai/index.json +135 -19
- package/.ai/skills/ui-translation.md +32 -14
- package/.ai/skills/version-migration.md +572 -0
- package/dist/components/Input/Input.js +23 -23
- package/llms.txt +87 -84
- package/package.json +2 -2
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
# Migrating from OUI to IDS v6
|
|
2
|
+
|
|
3
|
+
> **Guide:** `@iress-oss/ids-components`
|
|
4
|
+
> **Storybook:** [Migrating from OUI to IDS v6 in Storybook](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/docs/components_resources-migration-guides-from-oui-to-v6--docs)
|
|
5
|
+
|
|
6
|
+
This guide covers migrating from the legacy OUI component library (`@iress/oui`) to the Iress Design System v6 (`@iress-oss/ids-components`). It also covers upgrading existing IDS v4 (`@iress/components-react`) components, replacing Formik with IDS v6's React Hook Form integration, and updating your test infrastructure.
|
|
7
|
+
|
|
8
|
+
> **If you are migrating from IDS v5**, see [Migrating from v5](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/docs/components_resources-migration-guides-from-v5-to-v6--docs) instead — that guide focuses on v5-to-v6 breaking changes only.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
### Why migrate?
|
|
15
|
+
|
|
16
|
+
| Benefit | Details |
|
|
17
|
+
| ------------------- | ------------------------------------------------------------------ |
|
|
18
|
+
| **Consistency** | A single component library aligned with IDS v6 standards |
|
|
19
|
+
| **Accessibility** | Improved WCAG compliance built into every component |
|
|
20
|
+
| **Maintainability** | OUI and IDS v4 are legacy — IDS v6 is actively maintained |
|
|
21
|
+
| **TypeScript** | Full type-safety for components, styling props, and forms |
|
|
22
|
+
| **Performance** | React Hook Form is lighter than Formik; IDS v6 ships optimised CSS |
|
|
23
|
+
| **Bundle size** | Removing OUI, Formik, and Yup can save 200–300 KB |
|
|
24
|
+
|
|
25
|
+
### Migration scope
|
|
26
|
+
|
|
27
|
+
The migration covers three main areas:
|
|
28
|
+
|
|
29
|
+
1. **OUI → IDS v6** — Replace all `@iress/oui` components with `@iress-oss/ids-components` equivalents
|
|
30
|
+
2. **IDS v4 → IDS v6** — Update all `@iress/components-react` imports and adapt to v6 API changes
|
|
31
|
+
3. **Formik → React Hook Form** — Replace Formik forms with IDS v6's built-in form architecture
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 1. Dependencies
|
|
36
|
+
|
|
37
|
+
### Update `package.json`
|
|
38
|
+
|
|
39
|
+
Remove legacy packages and add IDS v6:
|
|
40
|
+
|
|
41
|
+
[View "UpdateDependencies" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--update-dependencies)
|
|
42
|
+
|
|
43
|
+
> `react-hook-form` is a peer dependency of `IressForm` in v6. You must add it to your own dependencies.
|
|
44
|
+
|
|
45
|
+
### Update imports
|
|
46
|
+
|
|
47
|
+
[View "UpdateImports" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--update-imports)
|
|
48
|
+
|
|
49
|
+
### Add the stylesheet
|
|
50
|
+
|
|
51
|
+
IDS v6 no longer injects CSS into the DOM. Add this **once** in your app entry point:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import '@iress-oss/ids-components/dist/style.css';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 2. OUI component mapping
|
|
60
|
+
|
|
61
|
+
### Direct mappings (low complexity)
|
|
62
|
+
|
|
63
|
+
These OUI components map directly to an IDS v6 equivalent with minimal prop changes.
|
|
64
|
+
|
|
65
|
+
#### Button → IressButton
|
|
66
|
+
|
|
67
|
+
[View "ButtonMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--button-migration)
|
|
68
|
+
|
|
69
|
+
| OUI prop | IDS v6 prop | Notes |
|
|
70
|
+
| ---------- | ----------- | ----------------------------------------------- |
|
|
71
|
+
| `variant` | `mode` | Same values: `primary`, `secondary`, `tertiary` |
|
|
72
|
+
| `loading` | `loading` | Unchanged |
|
|
73
|
+
| `disabled` | `disabled` | Unchanged |
|
|
74
|
+
| `type` | `type` | Unchanged |
|
|
75
|
+
|
|
76
|
+
> **New in v6:** `element` prop to render as a routing `Link`, `icon` prop for icon-only buttons, and `status` prop for `danger`/`success` states.
|
|
77
|
+
|
|
78
|
+
#### ProgressBar → IressProgress
|
|
79
|
+
|
|
80
|
+
[View "ProgressBarMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--progress-bar-migration)
|
|
81
|
+
|
|
82
|
+
Props are unchanged.
|
|
83
|
+
|
|
84
|
+
#### Badge → IressPill
|
|
85
|
+
|
|
86
|
+
[View "BadgeMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--badge-migration)
|
|
87
|
+
|
|
88
|
+
| OUI prop | IDS v6 prop |
|
|
89
|
+
| --------- | ----------- |
|
|
90
|
+
| `variant` | `mode` |
|
|
91
|
+
|
|
92
|
+
> In IDS v6, `IressBadge` has been renamed to `IressPill`. Use `IressPill` for static indicators and `IressTag` for interactive elements.
|
|
93
|
+
|
|
94
|
+
### Medium complexity
|
|
95
|
+
|
|
96
|
+
#### Modal → IressModal
|
|
97
|
+
|
|
98
|
+
[View "ModalMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--modal-migration)
|
|
99
|
+
|
|
100
|
+
| OUI prop | IDS v6 prop |
|
|
101
|
+
| --------- | -------------- |
|
|
102
|
+
| `isOpen` | `show` |
|
|
103
|
+
| `title` | `heading` |
|
|
104
|
+
| `onClose` | `onShowChange` |
|
|
105
|
+
|
|
106
|
+
#### DropdownButton → IressDropdownMenu / IressSelect / IressPopover
|
|
107
|
+
|
|
108
|
+
OUI's `DropdownButton` can be replaced by several IDS v6 components depending on the use case:
|
|
109
|
+
|
|
110
|
+
| Use case | IDS v6 component | When to use |
|
|
111
|
+
| ----------------------- | ------------------- | ------------------------------------------------------------------------------ |
|
|
112
|
+
| Menu of actions | `IressDropdownMenu` | Selecting from a list of options with built-in search and multi-select support |
|
|
113
|
+
| Form select | `IressSelect` | Selecting a value within a form |
|
|
114
|
+
| Custom dropdown content | `IressPopover` | Full control over the dropdown content |
|
|
115
|
+
|
|
116
|
+
**IressDropdownMenu example:**
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<IressOUI allowModeChange />
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
[View "DropdownMenuMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--dropdown-menu-migration)
|
|
123
|
+
|
|
124
|
+
**IressSelect example (in a form):**
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<IressOUI allowModeChange />
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
[View "DropdownSelectMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--dropdown-select-migration)
|
|
131
|
+
|
|
132
|
+
### Using styling props
|
|
133
|
+
|
|
134
|
+
#### Scrollable
|
|
135
|
+
|
|
136
|
+
OUI's `Scrollable` component is replaced by the `scrollable` styling prop, available on any IDS v6 component. It sets `overflow: auto` with design-system-styled scrollbars.
|
|
137
|
+
|
|
138
|
+
| Value | Behaviour |
|
|
139
|
+
| ------ | ---------------------- |
|
|
140
|
+
| `true` | Scroll on both axes |
|
|
141
|
+
| `"x"` | Horizontal scroll only |
|
|
142
|
+
| `"y"` | Vertical scroll only |
|
|
143
|
+
|
|
144
|
+
[View "ScrollableMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--scrollable-migration)
|
|
145
|
+
|
|
146
|
+
You can also use `scrollable` on any element — it is not limited to `IressPanel`:
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
<IressStack scrollable="y" style={{ maxHeight: '400px' }}>
|
|
150
|
+
<LongContent />
|
|
151
|
+
</IressStack>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 3. Form migration (Formik → IDS v6)
|
|
157
|
+
|
|
158
|
+
This is the most significant architectural change. IDS v6 forms use **React Hook Form** under the hood via `IressForm` and `IressFormField`.
|
|
159
|
+
|
|
160
|
+
### Key differences
|
|
161
|
+
|
|
162
|
+
| Formik | IDS v6 |
|
|
163
|
+
| ------------------------------------- | ---------------------------------------------- |
|
|
164
|
+
| `<Formik>` wrapper with render props | `<IressForm>` with declarative children |
|
|
165
|
+
| `<Field>` with `as` prop | `<IressFormField>` with `render` prop |
|
|
166
|
+
| Yup validation schemas | Per-field `rules` prop (React Hook Form rules) |
|
|
167
|
+
| `<ErrorMessage>` component | Automatic error display by `IressFormField` |
|
|
168
|
+
| Standalone `<Label>` + `<Input>` | Integrated `IressFormField` with `label` prop |
|
|
169
|
+
| `<FormGroup>` / `<Fieldset>` wrappers | `IressFormField` or `IressFieldGroup` |
|
|
170
|
+
|
|
171
|
+
### Basic form migration
|
|
172
|
+
|
|
173
|
+
**Before (Formik + OUI):**
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
|
|
177
|
+
const schema = Yup.object({
|
|
178
|
+
email: Yup.string().email('Invalid email').required('Email is required'),
|
|
179
|
+
password: Yup.string()
|
|
180
|
+
.min(8, 'Min 8 characters')
|
|
181
|
+
.required('Password is required'),
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
function LoginForm() {
|
|
185
|
+
return (
|
|
186
|
+
<Formik
|
|
187
|
+
initialValues={{ email: '', password: '' }}
|
|
188
|
+
validationSchema={schema}
|
|
189
|
+
onSubmit={handleSubmit}
|
|
190
|
+
>
|
|
191
|
+
{({ errors, touched }) => (
|
|
192
|
+
<Form>
|
|
193
|
+
<FormGroup>
|
|
194
|
+
<Label htmlFor="email">Email</Label>
|
|
195
|
+
<Field name="email" as={Input} type="email" />
|
|
196
|
+
{errors.email && touched.email && <span>{errors.email}</span>}
|
|
197
|
+
</FormGroup>
|
|
198
|
+
|
|
199
|
+
<FormGroup>
|
|
200
|
+
<Label htmlFor="password">Password</Label>
|
|
201
|
+
<Field name="password" as={Input} type="password" />
|
|
202
|
+
{errors.password && touched.password && (
|
|
203
|
+
<span>{errors.password}</span>
|
|
204
|
+
)}
|
|
205
|
+
</FormGroup>
|
|
206
|
+
|
|
207
|
+
<Button type="submit" variant="primary">
|
|
208
|
+
Login
|
|
209
|
+
</Button>
|
|
210
|
+
</Form>
|
|
211
|
+
)}
|
|
212
|
+
</Formik>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**After (IDS v6):**
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import {
|
|
221
|
+
IressForm,
|
|
222
|
+
IressFormField,
|
|
223
|
+
IressInput,
|
|
224
|
+
IressButton,
|
|
225
|
+
} from '@iress-oss/ids-components';
|
|
226
|
+
|
|
227
|
+
function LoginForm() {
|
|
228
|
+
return (
|
|
229
|
+
<IressForm
|
|
230
|
+
defaultValues={{ email: '', password: '' }}
|
|
231
|
+
onSubmit={handleSubmit}
|
|
232
|
+
>
|
|
233
|
+
<IressFormField
|
|
234
|
+
name="email"
|
|
235
|
+
label="Email"
|
|
236
|
+
render={(props) => <IressInput {...props} type="email" />}
|
|
237
|
+
rules={{
|
|
238
|
+
required: 'Email is required',
|
|
239
|
+
pattern: {
|
|
240
|
+
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
|
|
241
|
+
message: 'Invalid email',
|
|
242
|
+
},
|
|
243
|
+
}}
|
|
244
|
+
/>
|
|
245
|
+
|
|
246
|
+
<IressFormField
|
|
247
|
+
name="password"
|
|
248
|
+
label="Password"
|
|
249
|
+
render={(props) => <IressInput {...props} type="password" />}
|
|
250
|
+
rules={{
|
|
251
|
+
required: 'Password is required',
|
|
252
|
+
minLength: { value: 8, message: 'Min 8 characters' },
|
|
253
|
+
}}
|
|
254
|
+
/>
|
|
255
|
+
|
|
256
|
+
<IressButton type="submit" mode="primary">
|
|
257
|
+
Login
|
|
258
|
+
</IressButton>
|
|
259
|
+
</IressForm>
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Validation migration (Yup → rules)
|
|
265
|
+
|
|
266
|
+
| Yup | React Hook Form `rules` |
|
|
267
|
+
| ------------------------ | ---------------------------------------------------------------------- |
|
|
268
|
+
| `.required('msg')` | `required: 'msg'` |
|
|
269
|
+
| `.min(n, 'msg')` | `minLength: { value: n, message: 'msg' }` |
|
|
270
|
+
| `.max(n, 'msg')` | `maxLength: { value: n, message: 'msg' }` |
|
|
271
|
+
| `.email('msg')` | `pattern: { value: /…/, message: 'msg' }` |
|
|
272
|
+
| `.matches(regex, 'msg')` | `pattern: { value: regex, message: 'msg' }` |
|
|
273
|
+
| `.positive('msg')` | `validate: { positive: (v) => v > 0 \|\| 'msg' }` |
|
|
274
|
+
| `.integer('msg')` | `validate: { integer: (v) => Number.isInteger(Number(v)) \|\| 'msg' }` |
|
|
275
|
+
| `.url('msg')` | `pattern: { value: /^https?:\/\/.+/, message: 'msg' }` |
|
|
276
|
+
|
|
277
|
+
### Form component mapping
|
|
278
|
+
|
|
279
|
+
#### Input → IressFormField + IressInput
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
<IressOUI allowModeChange />
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
[View "InputMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--input-migration)
|
|
286
|
+
|
|
287
|
+
#### TextArea → IressFormField + IressInput (with rows)
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
<IressOUI allowModeChange />
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
[View "TextAreaMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--text-area-migration)
|
|
294
|
+
|
|
295
|
+
#### Label → IressFormField (label prop)
|
|
296
|
+
|
|
297
|
+
Labels are now integrated into `IressFormField` — no separate component needed:
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
<IressOUI allowModeChange />
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
[View "LabelMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--label-migration)
|
|
304
|
+
|
|
305
|
+
#### FormGroup / Fieldset → IressFormField or IressFieldGroup
|
|
306
|
+
|
|
307
|
+
`FormGroup` functionality is built into `IressFormField`. For `Fieldset` grouping, use `IressFieldGroup` which provides a semantic `<fieldset>` with a legend:
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
<IressOUI allowModeChange />
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
[View "FieldsetMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--fieldset-migration)
|
|
314
|
+
|
|
315
|
+
#### RadioGroup → IressFormField + IressRadioGroup
|
|
316
|
+
|
|
317
|
+
```tsx
|
|
318
|
+
<IressOUI allowModeChange />
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
[View "RadioGroupMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--radio-group-migration)
|
|
322
|
+
|
|
323
|
+
#### Checkbox → IressFormField + IressCheckbox
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
<IressOUI allowModeChange />
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
[View "CheckboxMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--checkbox-migration)
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## 4. IDS v4 → v6 component changes
|
|
334
|
+
|
|
335
|
+
If your project also uses IDS v4 (`@iress/components-react`), these components need updating alongside the OUI migration.
|
|
336
|
+
|
|
337
|
+
### Package import
|
|
338
|
+
|
|
339
|
+
All imports change from `@iress/components-react` to `@iress-oss/ids-components`. Component names stay the same.
|
|
340
|
+
|
|
341
|
+
### Breaking changes
|
|
342
|
+
|
|
343
|
+
| Component | Change | Migration |
|
|
344
|
+
| ------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------ |
|
|
345
|
+
| `IressButton` | `variant` → `mode` | Find and replace |
|
|
346
|
+
| `IressAlert` | `variant` → `status`; `error` → `danger` | Find and replace |
|
|
347
|
+
| `IressModal` | `isOpen` → `show`, `title` → `heading`, `onClose` → `onShowChange` | Find and replace |
|
|
348
|
+
| `IressForm` | Complete React Hook Form architecture | See [Form migration](#3-form-migration-formik--ids-v6) |
|
|
349
|
+
| `IressField` → `IressFormField` | Renamed; uses `render` prop pattern | See [Form migration](#3-form-migration-formik--ids-v6) |
|
|
350
|
+
| `IressText` | `variant` → `textStyle`, `mode` → `color`, `align` → `textAlign` | Find and replace |
|
|
351
|
+
| `IressStack` | `gutter` → `gap` | Find and replace |
|
|
352
|
+
| `IressDivider` | `gutter` removed | Use `my` / `mx` styling props |
|
|
353
|
+
| `IressBadge` → `IressPill` | Renamed | Find and replace |
|
|
354
|
+
|
|
355
|
+
### Low-risk components (unchanged API)
|
|
356
|
+
|
|
357
|
+
These components only need an import path update:
|
|
358
|
+
|
|
359
|
+
- `IressPanel`
|
|
360
|
+
- `IressInline`
|
|
361
|
+
- `IressIcon`
|
|
362
|
+
- `IressSkeleton`
|
|
363
|
+
- `IressSpinner`
|
|
364
|
+
- `IressProgress`
|
|
365
|
+
|
|
366
|
+
> For a comprehensive list of all v5-to-v6 component changes, see [Migrating from v5](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/docs/components_resources-migration-guides-from-v5-to-v6--docs).
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## 5. Testing migration
|
|
371
|
+
|
|
372
|
+
### Remove IDS v4 test utilities
|
|
373
|
+
|
|
374
|
+
IDS v6 uses standard React Testing Library — no special test utilities needed.
|
|
375
|
+
|
|
376
|
+
[View "RemoveTestUtils" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--remove-test-utils)
|
|
377
|
+
|
|
378
|
+
### Update test patterns
|
|
379
|
+
|
|
380
|
+
| IDS v4 pattern | IDS v6 pattern |
|
|
381
|
+
| ------------------------------------ | ---------------------------------------------------- |
|
|
382
|
+
| `idsFireEvent.click(el)` | `fireEvent.click(el)` or `await userEvent.click(el)` |
|
|
383
|
+
| `await findByTestId('x__button')` | `getByRole('button', { name: 'X' })` |
|
|
384
|
+
| `mockLazyLoadedComponents()` | Remove — components load synchronously |
|
|
385
|
+
| Async `findBy*` for component render | Synchronous `getBy*` in most cases |
|
|
386
|
+
|
|
387
|
+
### Prefer accessibility queries
|
|
388
|
+
|
|
389
|
+
[View "AccessibilityQueries" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--accessibility-queries)
|
|
390
|
+
|
|
391
|
+
### Update Jest / Vitest configuration
|
|
392
|
+
|
|
393
|
+
```tsx
|
|
394
|
+
<IressOUI allowModeChange />
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
[View "JestVitestConfig" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--jest-vitest-config)
|
|
398
|
+
|
|
399
|
+
### Form test migration
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
<IressOUI allowModeChange />
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
[View "FormTestMigration" example in Storybook →](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/story/components_resources-migration-guides-oui--form-test-migration)
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## 6. Styling migration
|
|
410
|
+
|
|
411
|
+
### CSS class changes
|
|
412
|
+
|
|
413
|
+
OUI and IDS v4 used different class naming conventions that no longer exist in v6:
|
|
414
|
+
|
|
415
|
+
```css
|
|
416
|
+
/* ❌ OUI classes — no longer exist */
|
|
417
|
+
.oui-button {
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* ❌ IDS v4 Stencil classes — no longer exist */
|
|
421
|
+
.sc-iress-button-h {
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/* ✅ IDS v6 — use styling props or design tokens */
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Use styling props instead of custom CSS
|
|
428
|
+
|
|
429
|
+
IDS v6 exposes global styling props on every component:
|
|
430
|
+
|
|
431
|
+
```tsx
|
|
432
|
+
// Spacing
|
|
433
|
+
<IressPanel p="lg" m="xl" />
|
|
434
|
+
|
|
435
|
+
// Responsive
|
|
436
|
+
<IressPanel p={{ base: 'sm', xl: 'lg' }} />
|
|
437
|
+
|
|
438
|
+
// Colour
|
|
439
|
+
<IressPanel bg="alt" />
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Use design tokens for custom styles
|
|
443
|
+
|
|
444
|
+
```css
|
|
445
|
+
/* ✅ Preferred — design tokens */
|
|
446
|
+
.custom-element {
|
|
447
|
+
color: var(--iress-color-text-primary);
|
|
448
|
+
padding: var(--iress-spacing-md);
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Cascade layers
|
|
453
|
+
|
|
454
|
+
All IDS v6 CSS lives in cascade layers. If your own un-layered CSS is being overridden, declare layer order:
|
|
455
|
+
|
|
456
|
+
```css
|
|
457
|
+
@layer reset, base, tokens, recipes, utilities;
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## 7. Common patterns
|
|
463
|
+
|
|
464
|
+
### Pattern 1: Simple form field
|
|
465
|
+
|
|
466
|
+
```tsx
|
|
467
|
+
<IressFormField
|
|
468
|
+
name="fieldName"
|
|
469
|
+
label="Field Label"
|
|
470
|
+
render={(props) => <IressInput {...props} />}
|
|
471
|
+
rules={{ required: 'Required' }}
|
|
472
|
+
/>
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Pattern 2: Complete form
|
|
476
|
+
|
|
477
|
+
```tsx
|
|
478
|
+
<IressForm onSubmit={handleSubmit} defaultValues={{ field1: '', field2: '' }}>
|
|
479
|
+
<IressFormField
|
|
480
|
+
name="field1"
|
|
481
|
+
label="First field"
|
|
482
|
+
render={(props) => <IressInput {...props} />}
|
|
483
|
+
/>
|
|
484
|
+
<IressFormField
|
|
485
|
+
name="field2"
|
|
486
|
+
label="Second field"
|
|
487
|
+
render={(props) => <IressInput {...props} />}
|
|
488
|
+
/>
|
|
489
|
+
<IressButton type="submit" mode="primary">
|
|
490
|
+
Submit
|
|
491
|
+
</IressButton>
|
|
492
|
+
</IressForm>
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### Pattern 3: Modal with form
|
|
496
|
+
|
|
497
|
+
```tsx
|
|
498
|
+
<IressModal show={isOpen} onShowChange={setIsOpen} heading="Edit item">
|
|
499
|
+
<IressForm onSubmit={handleSubmit}>
|
|
500
|
+
<IressFormField
|
|
501
|
+
name="name"
|
|
502
|
+
label="Name"
|
|
503
|
+
render={(props) => <IressInput {...props} />}
|
|
504
|
+
/>
|
|
505
|
+
<IressButton type="submit" mode="primary">
|
|
506
|
+
Save
|
|
507
|
+
</IressButton>
|
|
508
|
+
</IressForm>
|
|
509
|
+
</IressModal>
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Pattern 4: Contextual menu
|
|
513
|
+
|
|
514
|
+
```tsx
|
|
515
|
+
<IressContextualMenu
|
|
516
|
+
items={[
|
|
517
|
+
{ key: 'edit', label: 'Edit', onClick: handleEdit },
|
|
518
|
+
{ key: 'delete', label: 'Delete', onClick: handleDelete },
|
|
519
|
+
]}
|
|
520
|
+
/>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## 8. Common gotchas
|
|
526
|
+
|
|
527
|
+
| Problem | Cause | Solution |
|
|
528
|
+
| ------------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------- |
|
|
529
|
+
| Components have no styles | Missing CSS import | Add `import '@iress-oss/ids-components/dist/style.css'` to your app entry |
|
|
530
|
+
| Form validation not working | Using HTML5 attributes (`required`, `maxLength`) | Move all validation to the `rules` prop on `IressFormField` |
|
|
531
|
+
| Modal won't close | Using `isOpen` prop | Rename to `show` |
|
|
532
|
+
| Button variant not applying | Using `variant` prop | Rename to `mode` |
|
|
533
|
+
| Tests fail with "Cannot find module" | Jest can't transform IDS v6 | Update `transformIgnorePatterns` in your test config |
|
|
534
|
+
| `idsFireEvent` not found | Using removed IDS v4 test utils | Replace with standard `fireEvent` from React Testing Library |
|
|
535
|
+
| Form fields render without labels | Using standalone `<Label>` | Move the label text into the `label` prop on `IressFormField` |
|
|
536
|
+
| Custom CSS overriding components | Cascade layer ordering | Declare `@layer` order in your stylesheet |
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## 9. Full component reference
|
|
541
|
+
|
|
542
|
+
| OUI component | IDS v6 equivalent | Complexity | Notes |
|
|
543
|
+
| ---------------- | ---------------------------------------------------- | ---------- | -------------------------------------- |
|
|
544
|
+
| `Button` | `IressButton` | Low | `variant` → `mode` |
|
|
545
|
+
| `Input` | `IressFormField` + `IressInput` | High | Requires form context |
|
|
546
|
+
| `TextArea` | `IressFormField` + `IressInput` | High | Use `rows` prop |
|
|
547
|
+
| `Label` | `IressFormField` `label` prop | Medium | No separate component |
|
|
548
|
+
| `FormGroup` | `IressFormField` | High | Built-in to FormField |
|
|
549
|
+
| `Fieldset` | `IressFieldGroup` | Low | Use `label` prop |
|
|
550
|
+
| `RadioGroup` | `IressFormField` + `IressRadioGroup` | High | Requires form context |
|
|
551
|
+
| `Radio` | `IressRadio` | Medium | Must be in `IressRadioGroup` |
|
|
552
|
+
| `Checkbox` | `IressFormField` + `IressCheckbox` | Medium | — |
|
|
553
|
+
| `Modal` | `IressModal` | Medium | `isOpen` → `show`, `title` → `heading` |
|
|
554
|
+
| `DropdownButton` | `IressDropdownMenu` / `IressSelect` / `IressPopover` | Medium | Depends on use case — see above |
|
|
555
|
+
| `ProgressBar` | `IressProgress` | Low | Props unchanged |
|
|
556
|
+
| `Badge` | `IressPill` | Low | `variant` → `mode` |
|
|
557
|
+
| `Scrollable` | `scrollable` styling prop | Low | Available on any component |
|
|
558
|
+
|
|
559
|
+
| IDS v4 component | IDS v6 change | Complexity |
|
|
560
|
+
| -------------------------- | ----------------------------------------- | ---------- |
|
|
561
|
+
| `IressButton` | `variant` → `mode` | Low |
|
|
562
|
+
| `IressAlert` | `variant` → `status`; `error` → `danger` | Low |
|
|
563
|
+
| `IressText` | `variant` → `textStyle`, `mode` → `color` | Low |
|
|
564
|
+
| `IressStack` | `gutter` → `gap` | Low |
|
|
565
|
+
| `IressModal` | `isOpen` → `show`, `title` → `heading` | Medium |
|
|
566
|
+
| `IressForm` / `IressField` | React Hook Form architecture | High |
|
|
567
|
+
| `IressBadge` | Renamed to `IressPill` | Low |
|
|
568
|
+
| `IressPanel` | Import path only | Low |
|
|
569
|
+
| `IressInline` | Import path only | Low |
|
|
570
|
+
| `IressDivider` | `gutter` removed; use `my`/`mx` | Low |
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
*View in Storybook: [https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/docs/components_resources-migration-guides-from-oui-to-v6--docs](https://main--691abcc79dfa560a36d0a74f.chromatic.com/?path=/docs/components_resources-migration-guides-from-oui-to-v6--docs)*
|