import React from 'react';
// React context to communicate the active context panel width up and down the tree.
//
// We need the width prop from the ContextPanel component.
//
// However, the actual component might be deeply nested inside the contextPanel.
// For example, in the template context panel storybook, we wrap it in 2 higher order components.
//
// Changing the max-width on the main editor container happens above where the gets rendered.
//
// To subtract the context panel width from the available real estate, we use the Provider and Consumer.
//
// positionedOverEditor is used to determine whether the context panel is positioned over the Editor so we are
// able to position and add margins to handle certain elements like inline comment dialogues overlapping the context
// panel
export type ContextPanelContext = {
width: number;
positionedOverEditor: boolean;
broadcastWidth: (width: number) => void;
broadcastPosition: (positionedOverEditor: boolean) => void;
};
const { Provider, Consumer } = React.createContext({
width: 0,
positionedOverEditor: false,
broadcastWidth: () => {},
broadcastPosition: () => {},
});
export type ContextPanelProviderState = {
width?: number;
positionedOverEditor?: boolean;
};
export class ContextPanelWidthProvider extends React.Component<
any,
ContextPanelProviderState
> {
state = { width: 0, positionedOverEditor: false };
constructor(props: any) {
super(props);
}
broadcastSidebarWidth = (width: number) => {
if (width !== this.state.width) {
this.setState({
width,
});
}
};
broadcastPosition = (positionedOverEditor: boolean) => {
if (positionedOverEditor !== this.state.positionedOverEditor) {
this.setState({
positionedOverEditor,
});
}
};
render() {
const { width, positionedOverEditor } = this.state;
return (
{this.props.children}
);
}
}
export { Provider as ContextPanelProvider, Consumer as ContextPanelConsumer };