Files
site-builder/craft/src/panels/left/LayerFocusContext.tsx
T

45 lines
1.5 KiB
TypeScript
Raw Normal View History

import React, { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';
/**
* Carries "the user clicked a virtual Layers row -- scroll that array item's
* card into view" from the Layers panel (left) to the array editors (right).
*
* Deliberately a request, not a command: consumers that don't implement
* scrolling simply ignore it. Selecting the parent node always happens in
* LayersPanel itself, so a click is useful even with no consumer at all.
*/
export interface LayerFocusRequest {
nodeId: string;
prop: string;
index: number;
/** Bumped on every request so an identical repeat still re-fires effects. */
nonce: number;
}
export interface LayerFocusValue {
focus: LayerFocusRequest | null;
requestFocus(nodeId: string, prop: string, index: number): void;
}
const LayerFocusContext = createContext<LayerFocusValue>({
focus: null,
requestFocus: () => {},
});
export const useLayerFocus = (): LayerFocusValue => useContext(LayerFocusContext);
export const LayerFocusProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [focus, setFocus] = useState<LayerFocusRequest | null>(null);
const nonceRef = useRef(0);
const requestFocus = useCallback((nodeId: string, prop: string, index: number) => {
nonceRef.current += 1;
setFocus({ nodeId, prop, index, nonce: nonceRef.current });
}, []);
const value = useMemo(() => ({ focus, requestFocus }), [focus, requestFocus]);
return <LayerFocusContext.Provider value={value}>{children}</LayerFocusContext.Provider>;
};