Skip to content

Commit ca08a72

Browse files
committed
docs(skills): fix refs and forms guidance
1 parent 6fa646b commit ca08a72

File tree

3 files changed

+48
-47
lines changed

3 files changed

+48
-47
lines changed

skills/igniteui-react-components/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Use [COMPONENT-CATALOGUE.md](./reference/COMPONENT-CATALOGUE.md) to map any UI n
130130

131131
### Refs
132132

133-
- Use `useRef<HTMLElement>(null)` and cast to access imperative API
133+
- Use `useRef<IgrDialog>(null)` with the component type:
134134
- See [REFS-FORMS.md](./reference/REFS-FORMS.md)
135135

136136
### Charts, Gauges, Maps & Grid Lite

skills/igniteui-react-components/reference/REFS-FORMS.md

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
## Refs & Imperative API
44

5-
Use `useRef` to access the underlying web component element and call imperative methods (e.g., showing/hiding a dialog, focusing an input):
5+
Use `useRef` to access the underlying web component element and call imperative methods (e.g., showing/hiding a dialog, focusing an input).
6+
Components from `igniteui-react`, `igniteui-react-grids` and `igniteui-react-dockmanager` are React Function Components forward the native element to `useRef` and expose alias with the same name for accessing the custom element API:
67

78
```tsx
89
import { useRef } from 'react';
910
import { IgrDialog, IgrButton, IgrInput } from 'igniteui-react';
1011

1112
function MyPage() {
12-
const dialogRef = useRef<HTMLElement>(null);
13-
const inputRef = useRef<HTMLElement>(null);
13+
const dialogRef = useRef<IgrDialog>(null);
14+
const inputRef = useRef<IgrInput>(null);
1415

1516
const openDialog = () => {
1617
// Access the underlying web component and call its methods
17-
(dialogRef.current as any)?.show();
18+
dialogRef.current?.show();
1819
};
1920

2021
const focusInput = () => {
@@ -29,7 +30,7 @@ function MyPage() {
2930

3031
<IgrDialog ref={dialogRef} title="Confirmation">
3132
<p>Are you sure?</p>
32-
<IgrButton slot="footer" onClick={() => (dialogRef.current as any)?.hide()}>
33+
<IgrButton slot="footer" onClick={() => dialogRef.current?.hide()}>
3334
<span>Close</span>
3435
</IgrButton>
3536
</IgrDialog>
@@ -45,6 +46,35 @@ function MyPage() {
4546

4647
> **Tip:** The ref gives you direct access to the web component's DOM element. You can call any method documented in the web component API.
4748
49+
50+
## Uncontrolled Components
51+
52+
`igniteui-react` Inputs integrate with the native form handling through Element internals, allowing to take advantage of the native state management adn validation to create intuitive, straight-forward forms:
53+
54+
```tsx
55+
import { useRef } from 'react';
56+
import { IgrInput, IgrButton } from 'igniteui-react';
57+
58+
function SimpleForm() {
59+
const nameRef = useRef<IgrInput>(null);
60+
61+
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
62+
// e.preventDefault(); // optionally prevent default submit form custom handling
63+
const formData = new FormData(e.target);
64+
};
65+
66+
return (
67+
<form onSubmit={handleSubmit}>
68+
<IgrInput name="name" label="Name" required={true} />
69+
<IgrInput name="description" label="description" minLength={0}>
70+
<IgrButton type="submit">
71+
<span>Submit</span>
72+
</IgrButton>
73+
</form>
74+
);
75+
}
76+
```
77+
4878
## Controlled Components with `useState`
4979

5080
Wire up Ignite UI form components with React state for controlled behavior:
@@ -63,15 +93,13 @@ function ProfileForm() {
6393
<IgrInput
6494
label="Name"
6595
value={name}
66-
onInput={(e: CustomEvent) =>
67-
setName((e.target as HTMLInputElement).value)
68-
}
96+
onInput={(e: CustomEvent<string>) => setName(e.detail) }
6997
/>
7098

7199
<IgrCheckbox
72100
checked={newsletter}
73-
onChange={(e: CustomEvent) =>
74-
setNewsletter((e.target as any).checked)
101+
onChange={(e: CustomEvent<IgcCheckboxChangeEventArgs>) =>
102+
setNewsletter(e.detail.checked)
75103
}
76104
>
77105
Subscribe to newsletter
@@ -80,8 +108,8 @@ function ProfileForm() {
80108
<IgrSelect
81109
label="Role"
82110
value={role}
83-
onChange={(e: CustomEvent) =>
84-
setRole((e.detail as any).value)
111+
onChange={(e: CustomEvent<IgcSelectItemComponent>) =>
112+
setRole(e.detail.value)
85113
}
86114
>
87115
<IgrSelectItem value="user">User</IgrSelectItem>
@@ -93,33 +121,6 @@ function ProfileForm() {
93121
}
94122
```
95123

96-
## Uncontrolled Components
97-
98-
For simpler scenarios, omit state and read the value on submit:
99-
100-
```tsx
101-
import { useRef } from 'react';
102-
import { IgrInput, IgrButton } from 'igniteui-react';
103-
104-
function SimpleForm() {
105-
const nameRef = useRef<HTMLElement>(null);
106-
107-
const handleSubmit = () => {
108-
const value = (nameRef.current as any)?.value;
109-
console.log('Name:', value);
110-
};
111-
112-
return (
113-
<form>
114-
<IgrInput ref={nameRef} label="Name" />
115-
<IgrButton onClick={handleSubmit}>
116-
<span>Submit</span>
117-
</IgrButton>
118-
</form>
119-
);
120-
}
121-
```
122-
123124
## React Hook Form Integration
124125

125126
Ignite UI components are form-associated web components. You can integrate them with React Hook Form using `Controller`:
@@ -151,8 +152,8 @@ function SignUpForm() {
151152
label="Email"
152153
type="email"
153154
value={field.value || ''}
154-
onInput={(e: CustomEvent) =>
155-
field.onChange((e.target as HTMLInputElement).value)
155+
onInput={(e: CustomEvent<string>) =>
156+
field.onChange(e.detail)
156157
}
157158
onBlur={() => field.onBlur()}
158159
invalid={!!errors.email}
@@ -168,8 +169,8 @@ function SignUpForm() {
168169
render={({ field }) => (
169170
<IgrCheckbox
170171
checked={field.value || false}
171-
onChange={(e: CustomEvent) =>
172-
field.onChange((e.target as any).checked)
172+
onChange={(e: CustomEvent<IgcCheckboxChangeEventArgs>) =>
173+
field.onChange(e.detail.checked)
173174
}
174175
>
175176
I accept the terms and conditions

skills/igniteui-react-components/reference/TROUBLESHOOTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ const handleChange = (e: CustomEvent) => {
7979

8080
## Issue: Component methods not accessible
8181

82-
**Solution:** Use `useRef` and cast to the underlying web component type:
82+
**Solution:** Use `useRef` with the component type:
8383

8484
```tsx
85-
const dialogRef = useRef<HTMLElement>(null);
85+
const dialogRef = useRef<IgrDialog>(null);
8686

8787
// Call imperative method
88-
(dialogRef.current as any)?.show();
88+
dialogRef.current?.show();
8989
```
9090

9191
## Issue: Chart / gauge / map does not render or is invisible

0 commit comments

Comments
 (0)