Skip to content

Commit 7bcbb64

Browse files
committed
docs: improve writing and add details
1 parent 5e73886 commit 7bcbb64

File tree

4 files changed

+142
-130
lines changed

4 files changed

+142
-130
lines changed

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ yarn.lock
77
*generated*
88
storybook-static
99

10+
# document
11+
*.mdx
12+
1013
# VSCode personal settings
1114
.vscode/launch.json
1215
.vscode/tasks.json

docs/pages/how-to/data-type.mdx

Lines changed: 86 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -5,111 +5,83 @@ import JsonViewerWithWidget from '../../examples/JsonViewerWithWidget'
55

66
# Defining data types for any data
77

8-
By utlizing the `defineDataType` function, you can define data types for any data structure.\
9-
This is useful in several cases:
10-
11-
- Add support for data type that is not supported by the library
12-
- Customize / extend the appearance and functionality of a data type
13-
14-
## Explanation
15-
16-
Before we get into the details, let's take a look at the `defineDataType` function signature:
17-
18-
```ts
19-
function defineDataType<ValueType = unknown>(options: {
20-
/**
21-
* Type matcher - Whether the value belongs to the data type
22-
*/
23-
is: (value: unknown, path: Path) => boolean
24-
/**
25-
* transform the value to a string for editing
26-
*/
27-
serialize?: (value: ValueType) => string
28-
/**
29-
* parse the string back to a value
30-
* throw an error if the input is invalid
31-
* and the editor will ignore the change
32-
*/
33-
deserialize?: (value: string) => ValueType
34-
Component: ComponentType<DataItemProps<ValueType>>
35-
/**
36-
* if you want to provide a custom editor
37-
* you can use this prop to provide a custom editor
38-
*
39-
* _Note: You need to pass `serialize` and `deserialize` to enable this feature_
40-
*/
41-
Editor?: ComponentType<EditorProps<string>>
42-
PreComponent?: ComponentType<DataItemProps<ValueType>>
43-
PostComponent?: ComponentType<DataItemProps<ValueType>>
44-
})
45-
```
8+
The `defineDataType` function allows you to define custom data types for any data structure. This is useful for:
9+
10+
- Adding support for data types not supported by the library.
11+
- Customizing or extending the appearance and functionality of existing data types.
12+
13+
## Introduction
14+
15+
To define a data type using `defineDataType`, you provide an object with various properties, such as `is`, `Component`, `PreComponent`, `PostComponent`, and `Editor`. These properties enable you to specify how to match values of the data type, how to render them, and how to edit them.
16+
17+
Before we dive into the details of defining a data type, let's take a closer look at the object that you'll need to provide to `defineDataType`.
4618

4719
#### `is` - The Type Matcher
4820

49-
`is` is a function that takes a value and a path and returns `true` if the value is the type you want to define.
21+
The `is` function takes a value and a path and returns true if the value belongs to the data type being defined.
5022

5123
#### `Component` - The Renderer
5224

53-
`Component` is a React component that renders the value.\
54-
It receives a `DataItemProps` object as a `prop`.
25+
The `Component` prop is a React component that renders the value of the data type. It receives a `DataItemProps` object as a `prop`, which includes the following:
5526

56-
- `props.value` - The value to render
57-
- `props.inspect` - if the value is being inspected(expanded).
58-
- `props.setInspect` - you can use it to toggle the inspect state.
27+
- `props.value` - The value to render.
28+
- `props.inspect` - A Boolean flag indicating whether the value is being inspected (expanded).
29+
- `props.setInspect` - A function that can be used to toggle the inspect state.
5930

6031
#### `PreComponent` and `PostComponent`
6132

62-
For advanced use cases, you can also provide `PreComponent` and `PostComponent` to render before and after the value. This is useful if you want to add a button or implement an expandable view.
33+
For advanced use cases, you can provide `PreComponent` and `PostComponent` to render content before and after the value, respectively. This is useful if you want to add a button or implement an expandable view.
6334

6435
#### `Editor`
6536

66-
You need to provide `serialize` and `deserialize` to transform the value for editing. Using `Editor` component to provide a custom editor for the value **_stringified_** by `serialize`. Under the hood, the edited value will be parsed using `deserialize` and the result will be passed to `onChange` callback.
37+
To enable editing for a data type, you need to provide `serialize` and `deserialize` functions to convert the value to and from a string representation. You can then use the `Editor` component to provide a custom editor for the stringified value. When the user edits the value, it will be parsed using `deserialize`, and the result will be passed to the `onChange` callback.
6738

6839
## Examples
6940

7041
### Adding support for image
7142

72-
Let's say you have an object that looks like this:
43+
Suppose you have a JSON object that includes an image URL:
7344

7445
```json
7546
{
7647
"image": "https://i.imgur.com/1bX5QH6.jpg"
7748
}
7849
```
7950

80-
You might want to preview images in your JSON.\
81-
We can define a data type for it like this:
51+
If you want to preview images directly in your JSON, you can define a data type for images:
8252

8353
<Tabs items={['JS', 'TS']}>
8454
<Tab>
55+
8556
```jsx
8657
import { defineDataType } from '@textea/json-viewer'
8758

8859
const imageType = defineDataType({
89-
is: (value) => {
90-
if (typeof value !== 'string') return false
91-
try {
92-
const url = new URL(value)
93-
return url.pathname.endsWith('.jpg')
94-
} catch (\_) {
95-
return false
96-
}
97-
},
98-
Component: (props) => {
99-
return (
100-
<img
101-
height={48}
102-
width={48}
103-
src={props.value}
104-
alt={props.value}
105-
style={{ display: 'inline-block' }}
106-
/>
107-
)
108-
}
60+
is: (value) => {
61+
if (typeof value !== 'string') return false
62+
try {
63+
const url = new URL(value)
64+
return url.pathname.endsWith('.jpg')
65+
} catch {
66+
return false
67+
}
68+
},
69+
Component: (props) => {
70+
return (
71+
<img
72+
height={48}
73+
width={48}
74+
src={props.value}
75+
alt={props.value}
76+
style={{ display: 'inline-block' }}
77+
/>
78+
)
79+
}
10980
})
81+
```
11082

111-
````
11283
</Tab>
84+
11385
<Tab>
11486
```tsx
11587
import { defineDataType } from '@textea/json-viewer'
@@ -120,7 +92,7 @@ const imageType = defineDataType<string>({
12092
try {
12193
const url = new URL(value)
12294
return url.pathname.endsWith('.jpg')
123-
} catch (_) {
95+
} catch {
12496
return false
12597
}
12698
},
@@ -136,12 +108,12 @@ const imageType = defineDataType<string>({
136108
)
137109
}
138110
})
139-
````
111+
```
140112

141113
</Tab>
142114
</Tabs>
143115

144-
And then you can use it like this:
116+
And then use it like this:
145117

146118
```jsx {3,5}
147119
<JsonViewer
@@ -165,27 +137,28 @@ Let's add support for the [`URL`](https://developer.mozilla.org/en-US/docs/Web/A
165137
import { defineDataType } from '@textea/json-viewer'
166138

167139
const urlType = defineDataType({
168-
is: (value) => value instanceof URL,
169-
Component: (props) => {
170-
const url = props.value.toString()
171-
return (
172-
<a
173-
href={url}
174-
target='\_blank'
175-
rel='noopener noreferrer'
176-
style={{
140+
is: (value) => value instanceof URL,
141+
Component: (props) => {
142+
const url = props.value.toString()
143+
return (
144+
<a
145+
href={url}
146+
target='_blank'
147+
rel='noopener noreferrer'
148+
style={{
177149
cursor: 'pointer',
178150
color: '#1976d2',
179151
textDecoration: 'underline'
180-
}} >
181-
{url}
182-
</a>
183-
)
184-
}
152+
}}
153+
>
154+
{url}
155+
</a>
156+
)
157+
}
185158
})
186-
187-
````
159+
```
188160
</Tab>
161+
189162
<Tab>
190163
```tsx
191164
import { defineDataType } from '@textea/json-viewer'
@@ -210,12 +183,11 @@ const urlType = defineDataType<URL>({
210183
)
211184
}
212185
})
213-
````
214-
186+
```
215187
</Tab>
216188
</Tabs>
217189

218-
And then you can use it like this:
190+
And then use it like this:
219191

220192
```jsx {4,6}
221193
<JsonViewer
@@ -227,7 +199,7 @@ And then you can use it like this:
227199
/>
228200
```
229201

230-
Which will give you the following result 🎉
202+
It should looks like this 🎉
231203

232204
<br />
233205
<JsonViewerWithURL />
@@ -247,29 +219,30 @@ import { defineDataType, JsonViewer, stringType } from '@textea/json-viewer'
247219
import { Button } from '@mui/material'
248220

249221
const linkType = defineDataType({
250-
...stringType,
251-
is (value) {
252-
return typeof value === 'string' && value.startsWith('http')
253-
},
254-
PostComponent: (props) => (
255-
<Button
256-
variant='contained'
257-
size='small'
258-
href={props.value}
259-
target='\_blank'
260-
rel='noopener noreferrer'
261-
sx={{
222+
...stringType,
223+
is (value) {
224+
return typeof value === 'string' && value.startsWith('http')
225+
},
226+
PostComponent: (props) => (
227+
<Button
228+
variant='contained'
229+
size='small'
230+
href={props.value}
231+
target='_blank'
232+
rel='noopener noreferrer'
233+
sx={{
262234
display: 'inline-block',
263235
marginLeft: 1
264-
}} >
265-
Open
266-
<LinkIcon sx={{ strokeWidth: 2 }} />
267-
</Button>
268-
)
236+
}}
237+
>
238+
Open
239+
<LinkIcon sx={{ strokeWidth: 2 }} />
240+
</Button>
241+
)
269242
})
270-
271-
````
243+
```
272244
</Tab>
245+
273246
<Tab>
274247
```tsx
275248
import { defineDataType, JsonViewer, stringType } from '@textea/json-viewer'
@@ -297,7 +270,6 @@ const linkType = defineDataType<string>({
297270
</Button>
298271
)
299272
})
300-
````
301-
273+
```
302274
</Tab>
303275
</Tabs>

src/type.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,30 +50,51 @@ export type EditorProps<ValueType = unknown> = {
5050
setValue: Dispatch<ValueType>
5151
}
5252

53+
/**
54+
* A data type definition, including methods for checking, serializing, and deserializing values, as well as components for rendering and editing values.
55+
*
56+
* @template ValueType The type of the value represented by this data type
57+
*/
5358
export type DataType<ValueType = unknown> = {
5459
/**
55-
* Type matcher - Whether the value belongs to the data type
60+
* Determines whether a given value belongs to this data type.
61+
*
62+
* @param value The value to check
63+
* @param path The path to the value within the input data structure
64+
* @returns `true` if the value belongs to this data type, `false` otherwise
5665
*/
5766
is: (value: unknown, path: Path) => boolean
5867
/**
59-
* transform the value to a string for editing
68+
* Convert the value of this data type to a string for editing
6069
*/
6170
serialize?: (value: ValueType) => string
6271
/**
63-
* parse the string back to a value
64-
* throw an error if the input is invalid
65-
* and the editor will ignore the change
72+
* Converts a string representation of a value back to a value of this data type.
73+
*
74+
* Throws an error if the input is invalid, in which case the editor will ignore the change.
6675
*/
6776
deserialize?: (value: string) => ValueType
77+
/**
78+
* The main component used to render a value of this data type.
79+
*/
6880
Component: ComponentType<DataItemProps<ValueType>>
6981
/**
70-
* if you want to provide a custom editor
71-
* you can use this prop to provide a custom editor
82+
* An optional custom editor component for editing values of this data type.
7283
*
73-
* _Note: You need to pass `serialize` and `deserialize` to enable this feature_
84+
* You must also provide a `serialize` and `deserialize` function to enable this feature.
7485
*/
7586
Editor?: ComponentType<EditorProps<string>>
87+
/**
88+
* An optional component to render before the value.
89+
*
90+
* In collapsed mode, it will still be rendered as a prefix.
91+
*/
7692
PreComponent?: ComponentType<DataItemProps<ValueType>>
93+
/**
94+
* An optional component to render after the value.
95+
*
96+
* In collapsed mode, it will still be rendered as a suffix.
97+
*/
7798
PostComponent?: ComponentType<DataItemProps<ValueType>>
7899
}
79100

0 commit comments

Comments
 (0)