Skip to content

Commit e7bde0a

Browse files
authored
Merge pull request #8916 from marmelab/typescript-doc
Typescript documentation
2 parents d8a7b69 + bf8e90b commit e7bde0a

20 files changed

+574
-130
lines changed

docs/WithRecord.md

+27
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,33 @@ const PostList = () => (
5353
);
5454
```
5555

56+
## TypeScript
57+
58+
The `<WithRecord>` component accepts a generic parameter for the record type:
59+
60+
```tsx
61+
import { Show, SimpleShowLayout, WithRecord } from 'react-admin';
62+
63+
type Book = {
64+
id: number;
65+
author: string;
66+
}
67+
68+
const BookShow = () => (
69+
<Show>
70+
<SimpleShowLayout>
71+
<WithRecord<Book>
72+
label="author"
73+
render={book => {
74+
// TypeScript knows that book is of type Book
75+
return <span>{book.author}</span>}
76+
}
77+
/>
78+
</SimpleShowLayout>
79+
</Show>
80+
);
81+
```
82+
5683
## See Also
5784

5885
* [`useRecordContext`](./useRecordContext.md) is the hook version of this component.

docs/css/prism.css

+78-99
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,118 @@
1-
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+jsx */
2-
/**
3-
* prism.js default theme for JavaScript, CSS and HTML
4-
* Based on dabblet (http://dabblet.com)
5-
* @author Lea Verou
6-
*/
7-
1+
/* PrismJS 1.29.0
2+
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+jsx+tsx+typescript */
83
code[class*="language-"],
94
pre[class*="language-"] {
10-
color: black;
11-
background: none;
12-
text-shadow: 0 1px white;
13-
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
14-
text-align: left;
15-
white-space: pre;
16-
word-spacing: normal;
17-
word-break: normal;
18-
word-wrap: normal;
19-
line-height: 1.5;
20-
21-
-moz-tab-size: 4;
22-
-o-tab-size: 4;
23-
tab-size: 4;
24-
25-
-webkit-hyphens: none;
26-
-moz-hyphens: none;
27-
-ms-hyphens: none;
28-
hyphens: none;
29-
}
30-
31-
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
32-
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
33-
text-shadow: none;
34-
background: #b3d4fc;
35-
}
36-
37-
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
38-
code[class*="language-"]::selection, code[class*="language-"] ::selection {
39-
text-shadow: none;
40-
background: #b3d4fc;
41-
}
42-
5+
color: #000;
6+
background: 0 0;
7+
text-shadow: 0 1px #fff;
8+
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
9+
font-size: 1em;
10+
text-align: left;
11+
white-space: pre;
12+
word-spacing: normal;
13+
word-break: normal;
14+
word-wrap: normal;
15+
line-height: 1.5;
16+
-moz-tab-size: 4;
17+
-o-tab-size: 4;
18+
tab-size: 4;
19+
-webkit-hyphens: none;
20+
-moz-hyphens: none;
21+
-ms-hyphens: none;
22+
hyphens: none;
23+
}
24+
code[class*="language-"] ::-moz-selection,
25+
code[class*="language-"]::-moz-selection,
26+
pre[class*="language-"] ::-moz-selection,
27+
pre[class*="language-"]::-moz-selection {
28+
text-shadow: none;
29+
background: #b3d4fc;
30+
}
31+
code[class*="language-"] ::selection,
32+
code[class*="language-"]::selection,
33+
pre[class*="language-"] ::selection,
34+
pre[class*="language-"]::selection {
35+
text-shadow: none;
36+
background: #b3d4fc;
37+
}
4338
@media print {
44-
code[class*="language-"],
45-
pre[class*="language-"] {
46-
text-shadow: none;
47-
}
39+
code[class*="language-"],
40+
pre[class*="language-"] {
41+
text-shadow: none;
42+
}
4843
}
49-
50-
/* Code blocks */
5144
pre[class*="language-"] {
52-
padding: 1em;
53-
margin: .5em 0 1.275em 0;
54-
overflow: auto;
45+
padding: 1em;
46+
margin: 0.5em 0;
47+
overflow: auto;
5548
}
56-
5749
:not(pre) > code[class*="language-"],
5850
pre[class*="language-"] {
59-
background: #f5f2f0;
51+
background: #f5f2f0;
6052
}
61-
62-
/* Inline code */
6353
:not(pre) > code[class*="language-"] {
64-
padding: .1em;
65-
border-radius: .3em;
66-
white-space: normal;
54+
padding: 0.1em;
55+
border-radius: 0.3em;
56+
white-space: normal;
6757
}
68-
58+
.token.cdata,
6959
.token.comment,
70-
.token.prolog,
7160
.token.doctype,
72-
.token.cdata {
73-
color: slategray;
61+
.token.prolog {
62+
color: #708090;
7463
}
75-
7664
.token.punctuation {
77-
color: #999;
65+
color: #999;
7866
}
79-
80-
.namespace {
81-
opacity: .7;
67+
.token.namespace {
68+
opacity: 0.7;
8269
}
83-
84-
.token.property,
85-
.token.tag,
8670
.token.boolean,
87-
.token.number,
8871
.token.constant,
72+
.token.deleted,
73+
.token.number,
74+
.token.property,
8975
.token.symbol,
90-
.token.deleted {
91-
color: #905;
76+
.token.tag {
77+
color: #905;
9278
}
93-
94-
.token.selector,
9579
.token.attr-name,
96-
.token.string,
97-
.token.char,
9880
.token.builtin,
99-
.token.inserted {
100-
color: #690;
81+
.token.char,
82+
.token.inserted,
83+
.token.selector,
84+
.token.string {
85+
color: #690;
10186
}
102-
103-
.token.operator,
104-
.token.entity,
105-
.token.url,
10687
.language-css .token.string,
107-
.style .token.string {
108-
color: #a67f59;
109-
background: hsla(0, 0%, 100%, .5);
88+
.style .token.string,
89+
.token.entity,
90+
.token.operator,
91+
.token.url {
92+
color: #9a6e3a;
93+
background: hsla(0, 0%, 100%, 0.5);
11094
}
111-
11295
.token.atrule,
11396
.token.attr-value,
11497
.token.keyword {
115-
color: #07a;
98+
color: #07a;
11699
}
117-
100+
.token.class-name,
118101
.token.function {
119-
color: #DD4A68;
102+
color: #dd4a68;
120103
}
121-
122-
.token.regex,
123104
.token.important,
105+
.token.regex,
124106
.token.variable {
125-
color: #e90;
107+
color: #e90;
126108
}
127-
128-
.token.important,
129-
.token.bold {
130-
font-weight: bold;
109+
.token.bold,
110+
.token.important {
111+
font-weight: 700;
131112
}
132113
.token.italic {
133-
font-style: italic;
114+
font-style: italic;
134115
}
135-
136116
.token.entity {
137-
cursor: help;
117+
cursor: help;
138118
}
139-

docs/js/prism.js

+11-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/useAuthProvider.md

+36
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,39 @@ const UserName = ({ userId }) => {
5858
return <>{identity.fullName}</>;
5959
};
6060
```
61+
62+
## TypeScript
63+
64+
The `useAuthProvider` hook accepts a generic parameter for the `authProvider` type. This is useful when you added custom methods to your `authProvider`:
65+
66+
```tsx
67+
// In src/authProvider.ts
68+
import { AuthProvider } from 'react-admin';
69+
70+
export interface CustomAuthProviderMethods extends AuthProvider {
71+
refreshToken: () => Promise<any>
72+
}
73+
74+
export const authProvider: CustomAuthProviderMethods {
75+
// ...Standard authProvider methods
76+
refreshToken: () => {
77+
// Refresh the user authentication token
78+
}
79+
}
80+
81+
// In src/RefreshToken.tsx
82+
import { useAuthProvider } from 'react-admin';
83+
import { CustomAuthProviderMethods } from './src/authProvider';
84+
85+
const THIRTY_MINUTES = 1000 * 60 * 30;
86+
export const RefreshToken = () => {
87+
const authProvider = useAuthProvider<CustomAuthProviderMethods>();
88+
89+
useEffect(() => {
90+
const interval = useInterval(() => authProvider.refreshToken(), THIRTY_MINUTES);
91+
return () => clearInterval(interval);
92+
}, [authProvider]);
93+
94+
return null;
95+
};
96+
```

docs/useCreate.md

+11-4
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,23 @@ const LikeButton = () => {
5858
};
5959
```
6060

61-
**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:
61+
## TypeScript
62+
63+
The `useCreate` hook accepts a generic parameter for the record type and another for the error type:
6264

6365
```tsx
66+
type Product = {
67+
id: number;
68+
reference: string;
69+
}
70+
6471
useCreate<Product, Error>(undefined, undefined, {
6572
onError: (error) => {
66-
// error is an instance of Error.
73+
// TypeScript knows that error is of type Error
6774
},
6875
onSettled: (data, error) => {
69-
// data is an instance of Product.
70-
// error is an instance of Error.
76+
// TypeScript knows that data is of type Product
77+
// TypeScript knows that error is of type Error
7178
},
7279
})
7380
```

docs/useDataProvider.md

+46-2
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,56 @@ But the recommended way to query the Data Provider is to use the dataProvider me
4848

4949
**Tip**: The `dataProvider` returned by the hook is actually a *wrapper* around your Data Provider. This wrapper logs the user out if the dataProvider returns an error, and if the authProvider sees that error as an authentication error (via `authProvider.checkError()`).
5050

51-
**Tip**: If you use TypeScript, you can specify a record type for more type safety:
51+
## TypeScript
52+
53+
The `useDataProvider` hook accepts a generic parameter for the `dataProvider` type. This is useful when you added custom methods to your `dataProvider`:
54+
55+
```tsx
56+
// In src/dataProvider.ts
57+
import { DataProvider } from 'react-admin';
58+
59+
export interface DataProviderWithCustomMethods extends DataProvider {
60+
archive: (resource: string, params: {
61+
id: number;
62+
}) => Promise<any>
63+
}
64+
65+
export const dataProvider: DataProviderWithCustomMethods {
66+
// ...Standard dataProvider methods
67+
archive: (resource, params) => {
68+
// Call the archive endpoint and return a promise
69+
}
70+
}
71+
72+
// In src/ArchiveButton.tsx
73+
import { Button, useDataProvider } from 'react-admin';
74+
import ArchiveIcon from '@mui/icons-material/Archive';
75+
import { DataProviderWithCustomMethods } from './src/dataProvider';
76+
77+
export const ArchiveButton = () => {
78+
const dataProvider = useDataProvider<DataProviderWithCustomMethods>();
79+
const record = useRecord();
80+
81+
return (
82+
<Button
83+
label="Archive"
84+
onClick={() => {
85+
// TypeScript knows the archive method
86+
dataProvider.archive('resource', { id: record.id })
87+
}}
88+
>
89+
<ArchiveIcon />
90+
</Button>
91+
);
92+
};
93+
```
94+
95+
Besides, all the standard dataProvider methods accept a generic parameter for the record type:
5296

5397
```jsx
5498
dataProvider.getOne<Product>('users', { id: 123 })
5599
.then(({ data }) => {
56-
// \- type of data is Product
100+
// TypeScript knows that data is of type Product
57101
// ...
58102
})
59103
```

0 commit comments

Comments
 (0)