Skip to content

Commit 30340cf

Browse files
stipsancursoragent
andauthored
fix(@sanity/assist): render instruction preview icons from @sanity/icons v5 (#1503)
The instruction schema's prepare() returns a rendered <Icon symbol> element for instructions with a custom icon (since the icons v5 lazy-map migration), but the preview component still rendered props.icon as a component, crashing the instruction list with 'Element type is invalid ... got: <Icon />'. Handle both the element and the component (SparklesIcon fallback) shapes. Also add a README troubleshooting section for MISSING_EXPORT icon build errors, which come from code importing icons from the @sanity/icons package root - a pattern removed in v5 (the plugin itself already uses the per-icon export paths). Fixes #1495 Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Cody Olsen <stipsan@users.noreply.github.com>
1 parent ab86805 commit 30340cf

3 files changed

Lines changed: 38 additions & 6 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@sanity/assist": patch
3+
---
4+
5+
Fix a crash ("Element type is invalid … got: <Icon />") when rendering the instruction list for instructions with a custom icon. Since the `@sanity/icons` v5 migration the instruction preview received a rendered icon element but kept rendering it as a component; it now handles both. The README also gains a troubleshooting section for `MISSING_EXPORT` icon build errors, which come from code importing icons from the `@sanity/icons` package root — a pattern removed in v5 (this plugin already uses the per-icon export paths).

plugins/@sanity/assist/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [Table of contents](#table-of-contents)
66
- [About Sanity AI Assist](#about-sanity-ai-assist)
77
- [Installation](#installation)
8+
- [Build errors about missing icon exports](#build-errors-about-missing-icon-exports)
89
- [Setup](#setup)
910
- [Add the plugin](#add-the-plugin)
1011
- [Enabling the AI Assist API](#enabling-the-ai-assist-api)
@@ -57,6 +58,30 @@ npm install @sanity/assist sanity@latest
5758

5859
This plugin requires `sanity` version `3.26` or greater.
5960

61+
### Build errors about missing icon exports
62+
63+
This plugin depends on `@sanity/icons` v5, which [removed the per-icon exports from the package root](https://github.com/sanity-io/icons/releases/tag/v5.0.0): every icon now lives on its own export path. If `sanity build` or `sanity dev` fails with an error like
64+
65+
```
66+
[MISSING_EXPORT] "CopyIcon" is not exported by "node_modules/@sanity/icons/dist/index.js"
67+
```
68+
69+
the file referenced by the error still imports icons from the package root — usually the studio's own schema or structure code, or another dependency that has not been updated yet. Update those imports to the per-icon export paths:
70+
71+
```diff
72+
- import {CopyIcon, ListIcon} from '@sanity/icons'
73+
+ import {CopyIcon} from '@sanity/icons/Copy'
74+
+ import {ListIcon} from '@sanity/icons/List'
75+
```
76+
77+
Also make sure `@sanity/icons` is declared in the studio's own `package.json` when studio code imports it; which copy an undeclared import resolves to depends on package manager hoisting, and can change when installing or upgrading plugins.
78+
79+
If you cannot update the importing code right away (for example when it lives in a third-party package), pin `@sanity/icons` to v4 in the studio's own `package.json` until it catches up — v4 supports both import styles:
80+
81+
```sh
82+
npm install @sanity/icons@4
83+
```
84+
6085
## Setup
6186

6287
> **Note:** AI Assist is available for all projects on the Growth plan and up.

plugins/@sanity/assist/src/schemas/assistDocumentSchema.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {LockIcon} from '@sanity/icons/Lock'
55
import {SparklesIcon} from '@sanity/icons/Sparkles'
66
import {ThListIcon} from '@sanity/icons/ThList'
77
import {Box, Flex, Stack, Text, Tooltip} from '@sanity/ui'
8+
import {isValidElement} from 'react'
89
import {defineArrayMember, defineField, defineType, type ObjectSchemaType} from 'sanity'
910

1011
import {AssistDocumentForm} from '../assistDocument/components/AssistDocumentForm'
@@ -267,16 +268,17 @@ export const instruction = defineType({
267268
components: {
268269
input: InstructionInput,
269270
preview: (props: any) => {
270-
const Icon = props.icon
271+
// `icon` from `prepare` is either a rendered element (<Icon symbol={...} />) or a
272+
// component (the SparklesIcon fallback), so it cannot be rendered as <IconValue /> directly
273+
const IconValue = props.icon
274+
const icon = isValidElement(IconValue) ? IconValue : IconValue ? <IconValue /> : null
271275
return (
272276
<Flex gap={3} align="center" padding={2}>
273-
{Icon && (
277+
{icon ? (
274278
<Box flex="none">
275-
<Text size={1}>
276-
<Icon />
277-
</Text>
279+
<Text size={1}>{icon}</Text>
278280
</Box>
279-
)}
281+
) : null}
280282

281283
<Stack flex={1} gap={2}>
282284
<Text size={1} textOverflow="ellipsis" weight="medium">

0 commit comments

Comments
 (0)