Skip to content

Commit ad886e6

Browse files
Copilotstipsan
andauthored
feat: accept null | undefined for PortableText value prop (#306)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stipsan <81981+stipsan@users.noreply.github.com>
1 parent cc9801a commit ad886e6

5 files changed

Lines changed: 16 additions & 15 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@portabletext/react": minor
3+
---
4+
5+
The `value` prop now accepts `null | undefined`, and handles it appropriately, to reduce friction when using `<PortableText>` with [Sanity TypeGen](https://www.sanity.io/docs/apis-and-sdks/sanity-typegen)

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,4 @@ jspm_packages
5454

5555
.yalc
5656
yalc.lock
57+
package-lock.json

src/react-portable-text.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ export function PortableText<B extends TypedObject = PortableTextBlock>({
4040
onMissingComponent: missingComponentHandler = printWarning,
4141
}: PortableTextProps<B>): JSX.Element {
4242
const handleMissingComponent = missingComponentHandler || noop
43-
const blocks = Array.isArray(input) ? input : [input]
43+
let blocks: B[]
44+
if (Array.isArray(input)) {
45+
blocks = input
46+
} else if (input == null) {
47+
blocks = []
48+
} else {
49+
blocks = [input]
50+
}
4451
const nested = nestLists(blocks, listNestingMode || LIST_NEST_MODE_HTML)
4552

4653
const components = useMemo(() => {

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export interface PortableTextProps<
2424
/**
2525
* One or more blocks to render
2626
*/
27-
value: B | B[]
27+
value: B | B[] | null | undefined
2828

2929
/**
3030
* React components to use for rendering

test/typegen/typegen.test-d.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,14 @@ describe('TypeGen value prop compatibility', () => {
4848
const post = await fetchPost('foo')
4949

5050
// The `content` field from TypeGen is `Array<...> | null`
51-
// PortableText's `value` prop currently requires `TypedObject | TypedObject[]`
52-
// We want it to accept `null` (render nothing) or the TypeGen array directly
51+
// PortableText's `value` prop accepts `null` (renders nothing) and the TypeGen array directly
5352

54-
// @ts-expect-error - Currently fails because `value` doesn't accept `null`
55-
// In the future, this should work without the ts-expect-error
5653
;(<PortableText value={post!.content} />)
5754
})
5855

59-
test('Non-null PostQueryResult.content is assignable to value prop', async () => {
60-
const post = await fetchPost('foo')
61-
62-
// After removing null, the TypeGen array type IS compatible with value prop
63-
const content = post!.content!
64-
;(<PortableText value={content} />)
65-
})
66-
6756
test('AuthorQueryResult.bio should be assignable to value prop (currently fails)', async () => {
6857
const author = await fetchAuthor('123')
6958

70-
// @ts-expect-error - Same issue as above with null and optional fields
7159
;(<PortableText value={author!.bio} />)
7260
})
7361

0 commit comments

Comments
 (0)