From e23ed663a4a530aac8e4673885fdad4fd838d38e Mon Sep 17 00:00:00 2001 From: Ash Date: Wed, 12 Feb 2025 22:56:51 +0000 Subject: [PATCH] feat(sanity): add `CapabilityGate` component --- .../src/core/components/CapabilityGate.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 packages/sanity/src/core/components/CapabilityGate.tsx diff --git a/packages/sanity/src/core/components/CapabilityGate.tsx b/packages/sanity/src/core/components/CapabilityGate.tsx new file mode 100644 index 00000000000..8fbe2460359 --- /dev/null +++ b/packages/sanity/src/core/components/CapabilityGate.tsx @@ -0,0 +1,29 @@ +import {type ComponentType, type PropsWithChildren} from 'react' +import {useObservable} from 'react-rx' + +import {useRenderingContextStore} from '../store/_legacy/datastores' +import {type Capability} from '../store/renderingContext/types' + +type Props = PropsWithChildren<{ + capability: Capability +}> + +/** + * `CapabilityGate` only renders its children if the current Studio rendering context does not + * provide the specified capability. + * + * This allows consumers of the component to conveniently mark a portion of the React tree as + * providing a capability that may be overriden by the Studio rendering context. If the rendering + * context provides this capability, the local implementation will not be rendered. + */ +export const CapabilityGate: ComponentType = ({children, capability}) => { + const renderingContextStore = useRenderingContextStore() + const renderingContextCapabilities = useObservable(renderingContextStore.capabilities, {}) + const renderingContextHasCapability = renderingContextCapabilities[capability] === true + + if (renderingContextHasCapability) { + return null + } + + return children +}