diff --git a/packages/ui-dev-content/src/components/EditableContent.tsx b/packages/ui-dev-content/src/components/EditableContent.tsx index b403266..74e2ef8 100644 --- a/packages/ui-dev-content/src/components/EditableContent.tsx +++ b/packages/ui-dev-content/src/components/EditableContent.tsx @@ -55,8 +55,8 @@ export function EditableContent({ const registry = useContentRegistry(); useEffect(() => { - // Only register in development mode - if (!import.meta.env.DEV || !ref.current) { + // Only register in development mode and when provider is available + if (!import.meta.env.DEV || !ref.current || !registry) { return; } diff --git a/packages/ui-dev-content/src/core/ContentEditingContext.tsx b/packages/ui-dev-content/src/core/ContentEditingContext.tsx index 7e53a27..89c24af 100644 --- a/packages/ui-dev-content/src/core/ContentEditingContext.tsx +++ b/packages/ui-dev-content/src/core/ContentEditingContext.tsx @@ -148,9 +148,19 @@ export function ContentEditingProvider({ // ============================================================================ /** - * Access the content editing registry and state + * Access the content editing registry and state. + * Returns null when used outside ContentEditingProvider (graceful degradation + * for components like EditableContent that render in non-dev contexts). */ -export function useContentEditing() { +export function useContentEditing(): ContentEditingContextValue | null { + return useContext(ContentEditingContext); +} + +/** + * Access the content editing registry and state (strict version). + * Throws if used outside ContentEditingProvider. + */ +export function useContentEditingStrict(): ContentEditingContextValue { const context = useContext(ContentEditingContext); if (!context) { throw new Error('useContentEditing must be used within ContentEditingProvider'); @@ -159,35 +169,35 @@ export function useContentEditing() { } /** - * Access just the registry + * Access just the registry (returns null outside provider) */ export function useContentRegistry() { - const { registry } = useContentEditing(); - return registry; + const editing = useContentEditing(); + return editing?.registry ?? null; } /** - * Access detected content handles + * Access detected content handles (strict — requires provider) */ export function useContentHandles() { - const { handles, refreshHandles } = useContentEditing(); - return { handles, refresh: refreshHandles }; + const context = useContentEditingStrict(); + return { handles: context.handles, refresh: context.refreshHandles }; } /** - * Access overlay visibility state + * Access overlay visibility state (strict — requires provider) */ export function useOverlayState() { - const { overlayVisible, setOverlayVisible } = useContentEditing(); - return [overlayVisible, setOverlayVisible] as const; + const context = useContentEditingStrict(); + return [context.overlayVisible, context.setOverlayVisible] as const; } /** - * Access selected handle state + * Access selected handle state (strict — requires provider) */ export function useSelectedHandle() { - const { selectedHandle, setSelectedHandle } = useContentEditing(); - return [selectedHandle, setSelectedHandle] as const; + const context = useContentEditingStrict(); + return [context.selectedHandle, context.setSelectedHandle] as const; } // Re-export the singleton registry for direct access diff --git a/packages/ui-dev-content/src/hooks/useEditableContent.ts b/packages/ui-dev-content/src/hooks/useEditableContent.ts index 031d6c2..95aa70a 100644 --- a/packages/ui-dev-content/src/hooks/useEditableContent.ts +++ b/packages/ui-dev-content/src/hooks/useEditableContent.ts @@ -54,12 +54,12 @@ export function useEditableContent({ const registry = useContentRegistry(); useEffect(() => { - // Skip if dev-only and not in dev mode + // Skip if dev-only and not in dev mode, or if no provider available if (devOnly && !import.meta.env.DEV) { return; } - if (!ref.current) { + if (!ref.current || !registry) { return; }