Plugin Extensions: Expose PluginMeta generic in usePluginContext (#107577)

* Plugin Extensions: Expose PluginMeta generic in usePluginContext

* Plugin Extensions: Cast usePluginContext type on return

* Plugin Extensions: Fix PluginContext export
This commit is contained in:
Matt Cowley
2025-07-08 15:51:30 +02:00
committed by GitHub
parent 1e1fd3db38
commit dbbd9f23d1
6 changed files with 22 additions and 14 deletions
@@ -2,7 +2,7 @@ import { PropsWithChildren, ReactElement, useMemo } from 'react';
import { DataSourceInstanceSettings } from '../../types/datasource'; import { DataSourceInstanceSettings } from '../../types/datasource';
import { Context, DataSourcePluginContextType } from './PluginContext'; import { PluginContext, DataSourcePluginContextType } from './PluginContext';
export type DataSourcePluginContextProviderProps = { export type DataSourcePluginContextProviderProps = {
instanceSettings: DataSourceInstanceSettings; instanceSettings: DataSourceInstanceSettings;
@@ -16,5 +16,5 @@ export function DataSourcePluginContextProvider(
return { instanceSettings, meta: instanceSettings.meta }; return { instanceSettings, meta: instanceSettings.meta };
}, [instanceSettings]); }, [instanceSettings]);
return <Context.Provider value={value}>{children}</Context.Provider>; return <PluginContext.Provider value={value}>{children}</PluginContext.Provider>;
} }
@@ -1,14 +1,15 @@
import { createContext } from 'react'; import { createContext } from 'react';
import { KeyValue } from '../../types/data';
import { DataSourceInstanceSettings } from '../../types/datasource'; import { DataSourceInstanceSettings } from '../../types/datasource';
import { PluginMeta } from '../../types/plugin'; import { PluginMeta } from '../../types/plugin';
export interface PluginContextType { export interface PluginContextType<T extends KeyValue = KeyValue> {
meta: PluginMeta; meta: PluginMeta<T>;
} }
export interface DataSourcePluginContextType extends PluginContextType { export interface DataSourcePluginContextType<T extends KeyValue = KeyValue> extends PluginContextType<T> {
instanceSettings: DataSourceInstanceSettings; instanceSettings: DataSourceInstanceSettings;
} }
export const Context = createContext<PluginContextType | undefined>(undefined); export const PluginContext = createContext<PluginContextType | undefined>(undefined);
@@ -2,7 +2,7 @@ import { PropsWithChildren, ReactElement } from 'react';
import { PluginMeta } from '../../types/plugin'; import { PluginMeta } from '../../types/plugin';
import { Context } from './PluginContext'; import { PluginContext } from './PluginContext';
export type PluginContextProviderProps = { export type PluginContextProviderProps = {
meta: PluginMeta; meta: PluginMeta;
@@ -10,5 +10,5 @@ export type PluginContextProviderProps = {
export function PluginContextProvider(props: PropsWithChildren<PluginContextProviderProps>): ReactElement { export function PluginContextProvider(props: PropsWithChildren<PluginContextProviderProps>): ReactElement {
const { children, ...rest } = props; const { children, ...rest } = props;
return <Context.Provider value={rest}>{children}</Context.Provider>; return <PluginContext.Provider value={rest}>{children}</PluginContext.Provider>;
} }
@@ -1,5 +1,9 @@
import { KeyValue } from '../../types/data';
import { type DataSourcePluginContextType, type PluginContextType } from './PluginContext'; import { type DataSourcePluginContextType, type PluginContextType } from './PluginContext';
export function isDataSourcePluginContext(context: PluginContextType): context is DataSourcePluginContextType { export function isDataSourcePluginContext<T extends KeyValue = KeyValue>(
context: PluginContextType<T>
): context is DataSourcePluginContextType<T> {
return 'instanceSettings' in context && 'meta' in context; return 'instanceSettings' in context && 'meta' in context;
} }
@@ -1,9 +1,11 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { Context, PluginContextType } from './PluginContext'; import { KeyValue } from '../../types/data';
export function usePluginContext(): PluginContextType | null { import { PluginContext, PluginContextType } from './PluginContext';
const context = useContext(Context);
export function usePluginContext<T extends KeyValue = KeyValue>(): PluginContextType<T> | null {
const context = useContext(PluginContext);
// The extensions hooks (e.g. `usePluginLinks()`) are using this hook to check // The extensions hooks (e.g. `usePluginLinks()`) are using this hook to check
// if they are inside a plugin or not (core Grafana), so we should be able to return an empty state as well (`null`). // if they are inside a plugin or not (core Grafana), so we should be able to return an empty state as well (`null`).
@@ -11,5 +13,6 @@ export function usePluginContext(): PluginContextType | null {
return null; return null;
} }
return context; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return context as PluginContextType<T>;
} }
+1 -1
View File
@@ -435,7 +435,7 @@ export { type GroupingToMatrixTransformerOptions } from './transformations/trans
export { export {
type PluginContextType, type PluginContextType,
type DataSourcePluginContextType, type DataSourcePluginContextType,
Context as PluginContext, PluginContext,
} from './context/plugins/PluginContext'; } from './context/plugins/PluginContext';
export { type PluginContextProviderProps, PluginContextProvider } from './context/plugins/PluginContextProvider'; export { type PluginContextProviderProps, PluginContextProvider } from './context/plugins/PluginContextProvider';
export { export {