Skip to content

Commit b8e02ea

Browse files
spmonahankhmakoto
andauthored
Input: Writing migration guide from v0 and v8 (#22780)
* react-input: add v8->v9 upgrade guide Provides a basic example for v8 TextField and v9 Input along with a prop mapping table for the two implementations. * react-radio: fix typo Had text "v9" that should have been "v0". * react-input: add v0->v9 upgrade guide Adds a basic v0 Input to v9 Input upgrade example along with a prop mapping table. * feedback from pr * Update apps/public-docsite-v9/src/Concepts/Upgrade/FromV8/Components/Input.stories.mdx Co-authored-by: Makoto Morimoto <[email protected]> * Update apps/public-docsite-v9/src/Concepts/Upgrade/FromV0/Components/Input.stories.mdx Co-authored-by: Makoto Morimoto <[email protected]> Co-authored-by: Makoto Morimoto <[email protected]>
1 parent c45f4a6 commit b8e02ea

3 files changed

Lines changed: 241 additions & 1 deletion

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Meta } from '@storybook/addon-docs';
2+
3+
<Meta title="Concepts/Upgrading/from v0/Components/Input Upgrade" />
4+
5+
# Input Upgrade
6+
7+
Fluent UI Northstar (v0) provides the `Input` control to elicit input from users. Fluent UI v9 also provides an `Input` control but with a different API and feature set.
8+
9+
## Examples
10+
11+
### Basic Upgrade
12+
13+
Basic usage of `Input` v0 looks like
14+
15+
```tsx
16+
import * as React from 'react';
17+
import { Input, Text, Flex } from '@fluentui/react-northstar';
18+
19+
const InputV0BasicExample = () => {
20+
return <Input label="Search" />;
21+
};
22+
```
23+
24+
An equivalent `Input` v9 usage is
25+
26+
```tsx
27+
import * as React from 'react';
28+
import { Label, Input } from '@fluentui/react-components/unstable';
29+
import { useId } from '@fluentui/react-utilities';
30+
import { makeStyles } from '@griffel/react';
31+
32+
const useLayoutStyles = makeStyles({
33+
root: {
34+
maxWidth: '300px',
35+
display: 'flex',
36+
flexDirection: 'column',
37+
},
38+
});
39+
40+
const InputV9BasicExample = () => {
41+
const layoutStyles = useLayoutStyles();
42+
const inputId = useId('input');
43+
return (
44+
<div className={layoutStyles.root}>
45+
<Label htmlFor={inputId}>Search</Label>
46+
<Input id={inputId} />
47+
</div>
48+
);
49+
};
50+
```
51+
52+
## Prop Mapping
53+
54+
This table maps v0 `Input` props to the v9 `Input` equivalent.
55+
56+
| v0 | v9 | Notes |
57+
| ---------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
58+
| `accessibility` | n/a | |
59+
| `as` | n/a | |
60+
| `className` | `className` | |
61+
| `clearable` | n/a | Use `contentBefore` or `contentAfter` slots to add a `Button` to implement this behavior |
62+
| `defaultValue` | `defaultValue` | Mutually exclusive with `value` |
63+
| `design` | n/a | |
64+
| `error` | n/a | v9 `Input` does not handle error states |
65+
| `errorIndicator` | n/a | Use `contentBefore` or `contentAfter` slots to insert custom indicators |
66+
| `fluid` | n/a | |
67+
| `icon` | Use `contentBefore` or `contentAfter` slots | |
68+
| `iconPosition` | n/a | |
69+
| `inline` | n/a | |
70+
| `input` | `input` | This is a slot |
71+
| `inputRef` | Pass a `ref` to the `input` slot | |
72+
| `inverted` | `appearance` | |
73+
| `label` | Use `Label` component | Be sure to associate `Label` with `Input` via `htmlFor` |
74+
| `labelPosition` | n/a | |
75+
| `onChange` | `onChange` | |
76+
| `required` | `required` | This is the native HTML prop |
77+
| `showSuccessIndicator` | n/a | Use `contentBefore` or `contentAfter` slots to insert custom indicators |
78+
| `type` | `type` | Non text types like 'button' and 'checkbox' are not supported. Use `Button` or `Checkbox` component instead |
79+
| `value` | `value` | Mutually exclusive with `defaultValue` |
80+
| `variables` | n/a | Use `FluentProvider` to customize themes |
81+
| `wrapper` | `root` | This is a slot |

apps/public-docsite-v9/src/Concepts/Upgrade/FromV0/Components/RadioGroup.stories.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Meta } from '@storybook/addon-docs';
22

3-
<Meta title="Concepts/Upgrading/from v9/Components/RadioGroup Upgrade" />
3+
<Meta title="Concepts/Upgrading/from v0/Components/RadioGroup Upgrade" />
44

55
# RadioGroup Upgrade
66

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import { Meta } from '@storybook/addon-docs';
2+
3+
<Meta title="Concepts/Upgrading/from v8/Components/TextField to Input Upgrade" />
4+
5+
# TextField to Input Upgrade
6+
7+
Fluent UI v8 provides the `TextField` control for entering and editing text. In Fluent UI v9 `TextField` is replaced with `Input`.
8+
9+
While basic usage is largely the same, `Input` omits some features found in `TextField`, preferring to compose several components together for greater flexibility.
10+
11+
## Examples
12+
13+
### Basic Upgrade
14+
15+
Basic usage of `TextField` looks like
16+
17+
```tsx
18+
import * as React from 'react';
19+
import { TextField } from '@fluentui/react/lib/TextField';}
20+
import { Stack, IStackProps, IStackStyles } from '@fluentui/react/lib/Stack';
21+
22+
const columnProps: Partial<IStackProps> = {
23+
tokens: { childrenGap: 15 },
24+
styles: { root: { width: 300 } },
25+
};
26+
27+
const TextFieldV8BasicExample = () => {
28+
return <Stack {...columnProps}>
29+
<TextField label="Standard" />
30+
<TextField label="Disabled" disabled defaultValue="I am disabled" />
31+
<TextField label="Read-only" readOnly defaultValue="I am read-only" />
32+
<TextField label="Required " required />
33+
<TextField ariaLabel="Required without visible label" required />
34+
<TextField label="With error message" errorMessage="Error message" />
35+
</Stack>
36+
}
37+
```
38+
39+
An equivalent `Input` usage is:
40+
41+
```tsx
42+
import * as React from 'react';
43+
import { Text } from '@fluentui/react-components';
44+
import { Label, Input } from '@fluentui/react-components/unstable';
45+
import { useId } from '@fluentui/react-utilities';
46+
import { makeStyles } from '@griffel/react';
47+
48+
const useStackStyles = makeStyles({
49+
root: {
50+
maxWidth: '300px',
51+
display: 'flex',
52+
flexDirection: 'column',
53+
54+
'> * + *': {
55+
marginTop: '20px',
56+
},
57+
58+
'> div': {
59+
display: 'flex',
60+
flexDirection: 'column',
61+
},
62+
},
63+
});
64+
65+
const InputV9BasicExample = () => {
66+
const stackStyles = useStackStyles();
67+
const standardId = useId('standard');
68+
const disabledId = useId('disabled');
69+
const readonlyId = useId('readonly');
70+
const requiredId = useId('required');
71+
const errorId = useId('error');
72+
const errorMessageId = useId('error-message');
73+
74+
return (
75+
<div className={stackStyles.root}>
76+
<div>
77+
<Label htmlFor={standardId}>Standard</Label>
78+
<Input id={standardId} />
79+
</div>
80+
81+
<div>
82+
<Label htmlFor={disabledId}>Disabled</Label>
83+
<Input id={disabledId} disabled defaultValue="I am disabled" />
84+
</div>
85+
86+
<div>
87+
<Label htmlFor={readonlyId}>Read Only</Label>
88+
<Input id={readonlyId} readOnly defaultValue="I am read only" />
89+
</div>
90+
91+
<div>
92+
<Label htmlFor={requiredId} required>
93+
Required
94+
</Label>
95+
<Input id={requiredId} required defaultValue="I am required" />
96+
</div>
97+
98+
<div>
99+
<Input
100+
aria-label="Required without visible label"
101+
required
102+
defaultValue="I am required without a visible label"
103+
/>
104+
</div>
105+
106+
<div>
107+
<Label htmlFor={errorId}>With Error Message</Label>
108+
<Input id={errorId} aria-describedby={errorMessageId} />
109+
<Text id={errorMessageId}>Error message</Text>
110+
</div>
111+
</div>
112+
);
113+
};
114+
```
115+
116+
## Prop Mapping
117+
118+
This table maps v8 `TextField` props to the v9 `Input` equivalent.
119+
120+
| v8 | v9 | Notes |
121+
| -------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------ |
122+
| `componentRef` | `ref` | v9 provides access to the underlyig DOM node, not ITextField |
123+
| `elementRef` | `ref` | |
124+
| `multiline` | n/a | Use `Textarea` |
125+
| `resizable` | n/a | |
126+
| `autoAjustHeight` | n/a | See `Textarea` docs |
127+
| `underlined` | `appearance` | |
128+
| `borderless` | `appearance` | |
129+
| `label` | Use `Label` component | Be sure to associate `Label` with `Input` via `htmlFor` |
130+
| `onRenderLabel` | n/a | Use slots to customize `Input` |
131+
| `description` | n/a | Use another element like `Text` and associate it with `Input` via `aria-describedby` |
132+
| `onRenderDescription` | n/a | |
133+
| `onRenderInput` | n/a | Use slots to customize `Input` |
134+
| `prefix` | `contentBefore` | This is a slot not a `string` |
135+
| `suffix` | `contentAfter` | This is a slot not a `string` |
136+
| `onRenderPrefix` | n/a | Use slots to customize `Input` |
137+
| `onRenderSuffix` | n/a | Use slots to customize `Input` |
138+
| `iconProps` | Use `contentBefore` or `contentAfter` slot | |
139+
| `defaultValue` | `defaultValue` | Mutually exclusive with `value` |
140+
| `value` | `value` | Mutually exclusive with `defaultValue` |
141+
| `disabled` | `disabled` | |
142+
| `readOnly` | `readOnly` | In v9 this is the native HTML prop |
143+
| `invalid` | n/a | v9 `Input` does not handle validation states |
144+
| `errorMessage` | n/a | Use another element like `Text` and associate it with `Input` via `aria-describedby` |
145+
| `onChange` | `onChange` | Typescript types have changed |
146+
| `onNotifyValidationResult` | n/a | v9 `Input` does not handle validation |
147+
| `onGetErrorMessage` | n/a | v9 `Input` does not handle error states |
148+
| `deferredValidationTime` | n/a | v9 `Input` does not handle validation |
149+
| `className` | `className` | |
150+
| `inputClassName` | Use `input` slot | |
151+
| `ariaLabel` | `aria-label` | |
152+
| `validateOnFocusIn` | n/a | v9 `Input` does not handle validation |
153+
| `validateOnFocusOut` | n/a | v9 `Input` does not handle validation |
154+
| `validateOnLoad` | n/a | v9 `Input` does not handle validation |
155+
| `theme` | n/a | Use `FluentProvider` to customize themes |
156+
| `styles` | `className` | |
157+
| `autoComplete` | `autoComplete` | In v9 this is the native HTML prop |
158+
| `canRevealPassword` | n/a | v9 `Input` does not provide built in password reveal behavior |
159+
| `revealPasswordAriaLabel` | n/a | v9 `Input` does not provide built in password reveal behavior |

0 commit comments

Comments
 (0)