Files
Ashley Harrison 47f8717149 React: Use new JSX transform (#88802)
* update eslint, tsconfig + esbuild to handle new jsx transform

* remove thing that breaks the new jsx transform

* remove react imports

* adjust grafana-icons build

* is this the correct syntax?

* try this

* well this was much easier than expected...

* change grafana-plugin-configs webpack config

* fixes

* fix lockfile

* fix 2 more violations

* use path.resolve instead of require.resolve

* remove react import

* fix react imports

* more fixes

* remove React import

* remove import React from docs

* remove another react import
2024-06-25 12:43:47 +01:00

123 lines
3.5 KiB
TypeScript

import { css, cx } from '@emotion/css';
import { createRef, MutableRefObject, PureComponent } from 'react';
import * as React from 'react';
import SplitPane, { Split } from 'react-split-pane';
import { GrafanaTheme2 } from '@grafana/data';
import { getDragStyles } from '@grafana/ui';
import { config } from 'app/core/config';
interface Props {
splitOrientation?: Split;
paneSize: number;
splitVisible?: boolean;
minSize?: number;
maxSize?: number;
primary?: 'first' | 'second';
onDragFinished?: (size?: number) => void;
parentStyle?: React.CSSProperties;
paneStyle?: React.CSSProperties;
secondaryPaneStyle?: React.CSSProperties;
}
export class SplitPaneWrapper extends PureComponent<React.PropsWithChildren<Props>> {
//requestAnimationFrame reference
rafToken: MutableRefObject<number | null> = createRef();
componentDidMount() {
window.addEventListener('resize', this.updateSplitPaneSize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.updateSplitPaneSize);
}
updateSplitPaneSize = () => {
if (this.rafToken.current !== undefined) {
window.cancelAnimationFrame(this.rafToken.current!);
}
this.rafToken.current = window.requestAnimationFrame(() => {
this.forceUpdate();
});
};
onDragFinished = (size?: number) => {
document.body.style.cursor = 'auto';
if (this.props.onDragFinished && size !== undefined) {
this.props.onDragFinished(size);
}
};
onDragStarted = () => {
document.body.style.cursor = this.props.splitOrientation === 'horizontal' ? 'row-resize' : 'col-resize';
};
render() {
const {
children,
paneSize,
splitOrientation,
maxSize,
minSize,
primary,
parentStyle,
paneStyle,
secondaryPaneStyle,
splitVisible = true,
} = this.props;
let childrenArr = [];
if (Array.isArray(children)) {
childrenArr = children;
} else {
childrenArr.push(children);
}
// Limit options pane width to 90% of screen.
const styles = getStyles(config.theme2, splitVisible);
const dragStyles = getDragStyles(config.theme2);
// Need to handle when width is relative. ie a percentage of the viewport
const paneSizePx =
paneSize <= 1
? paneSize * (splitOrientation === 'horizontal' ? window.innerHeight : window.innerWidth)
: paneSize;
// the react split pane library always wants 2 children. This logic ensures that happens, even if one child is passed in
const childrenFragments = [
<React.Fragment key="leftPane">{childrenArr[0]}</React.Fragment>,
<React.Fragment key="rightPane">{childrenArr[1] || undefined}</React.Fragment>,
];
return (
<SplitPane
split={splitOrientation}
minSize={minSize}
maxSize={maxSize}
size={splitVisible ? paneSizePx : 0}
primary={splitVisible ? primary : 'second'}
resizerClassName={cx(
styles.resizer,
splitOrientation === 'horizontal' ? dragStyles.dragHandleHorizontal : dragStyles.dragHandleVertical
)}
onDragStarted={() => this.onDragStarted()}
onDragFinished={(size) => this.onDragFinished(size)}
style={parentStyle}
paneStyle={paneStyle}
pane2Style={secondaryPaneStyle}
>
{childrenFragments}
</SplitPane>
);
}
}
const getStyles = (theme: GrafanaTheme2, hasSplit: boolean) => {
return {
resizer: css({
display: hasSplit ? 'block' : 'none',
}),
};
};