diff --git a/packages/@sanity/base/sanity.json b/packages/@sanity/base/sanity.json
index a7b9e5683eac..956350e9541d 100644
--- a/packages/@sanity/base/sanity.json
+++ b/packages/@sanity/base/sanity.json
@@ -187,6 +187,10 @@
"name": "part:@sanity/base/query-container",
"description": "Wraps a query and passes down results as props to its child component"
},
+ {
+ "name": "part:@sanity/base/with-referring-documents",
+ "description": "A utility component that takes a document id and calls its child render prop with a list of documents referring to it"
+ },
{
"name": "part:@sanity/base/theme/layout/resets-style",
"description": "Provides resets for resetting browser styling"
@@ -410,6 +414,10 @@
"implements": "part:@sanity/base/query-container",
"path": "components/QueryContainer"
},
+ {
+ "implements": "part:@sanity/base/with-referring-documents",
+ "path": "components/WithReferringDocuments"
+ },
{
"implements": "part:@sanity/base/locale/formatters",
"path": "components/IntlWrapper.js"
diff --git a/packages/@sanity/base/src/components/WithReferringDocuments.js b/packages/@sanity/base/src/components/WithReferringDocuments.js
new file mode 100644
index 000000000000..cf3e0e033d5f
--- /dev/null
+++ b/packages/@sanity/base/src/components/WithReferringDocuments.js
@@ -0,0 +1,25 @@
+import documentStore from 'part:@sanity/base/datastore/document'
+import {withPropsStream} from 'react-props-stream'
+import {concat, of} from 'rxjs'
+import {distinctUntilChanged, map, switchMap} from 'rxjs/operators'
+
+const loadProps = receivedProps$ =>
+ receivedProps$.pipe(
+ distinctUntilChanged((prev, next) => prev.id === next.id),
+ switchMap(receivedProps =>
+ concat(
+ of({...receivedProps, referringDocuments: [], isLoading: true}),
+ documentStore.query('*[references($docId)] [0...101]', {docId: receivedProps.id}).pipe(
+ map(event => ({
+ ...receivedProps,
+ referringDocuments: event.documents,
+ isLoading: false
+ }))
+ )
+ )
+ )
+ )
+
+export const WithReferringDocuments = withPropsStream(loadProps, ({children, ...props}) =>
+ children(props)
+)
diff --git a/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js b/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js
index 8a33a4396b81..f3367e8d36eb 100644
--- a/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js
+++ b/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js
@@ -1,51 +1,26 @@
import React from 'react'
import PropTypes from 'prop-types'
-import documentStore from 'part:@sanity/base/datastore/document'
+import {WithReferringDocuments} from 'part:@sanity/base/with-referring-documents'
-export default function withReferringDocuments(Component) {
- return class extends React.PureComponent {
- static displayName = `enhanceWithAvailHeight(${Component.displayName || Component.name})`
-
- static propTypes = {
- published: PropTypes.object
- }
-
- state = {
- isLoading: false,
- referringDocuments: []
- }
-
- componentDidMount() {
- const {published} = this.props
- if (!published) {
- return
- }
- this.setState({isLoading: true})
- this.refSubscription = documentStore
- .query('*[references($docId)] [0...101]', {docId: published._id})
- .subscribe(event => {
- this.setState({
- referringDocuments: event.documents || [],
- isLoading: false
- })
- })
- }
-
- componentWillUnmount() {
- if (this.refSubscription) {
- this.refSubscription.unsubscribe()
- }
- }
+export default function enhanceWithReferringDocuments(Component) {
+ function EnhancedWithReferringDocuments(props) {
+ return (
+
+ {({isLoading, referringDocuments}) => (
+
+ )}
+
+ )
+ }
- render() {
- const {isLoading, referringDocuments} = this.state
- return (
-
- )
- }
+ EnhancedWithReferringDocuments.displayName = `enhanceWithReferringDocuments(${Component.displayName ||
+ Component.name})`
+ EnhancedWithReferringDocuments.propTypes = {
+ published: PropTypes.object
}
+ return EnhancedWithReferringDocuments
}