Skip to content

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Muhammad Ibragimov committed Dec 21, 2021
1 parent 6d4f5dc commit d50efb2
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 0 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export { Panel } from './panel';
export { PanelsContainer } from './panel_container';
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import { EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

export type ResizerMouseEvent = React.MouseEvent<HTMLButtonElement, MouseEvent>;
export type ResizerKeyDownEvent = React.KeyboardEvent<HTMLButtonElement>;

export interface Props {
onKeyDown: (eve: ResizerKeyDownEvent) => void;
onMouseDown: (eve: ResizerMouseEvent) => void;
className?: string;
}

export function Resizer(props: Props) {
return (
<button
{...props}
data-test-subj="splitPanelResizer"
aria-label={i18n.translate('console.splitPanel.adjustPanelSizeAriaLabel', {
defaultMessage: 'Press left/right to adjust panels size',
})}
>
<EuiIcon type="grabHorizontal" />
</button>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import { mount } from 'enzyme';
import toJson from 'enzyme-to-json';
import { spy } from 'sinon';

import { Panel } from './panel';
import { PanelsContainer } from './panel_container';

const testComponentA = <p style={{ width: '50px' }}>A</p>;
const testComponentB = <p style={{ width: '50px' }}>B</p>;

describe('Split panel', () => {
it('should render correctly', () => {
const panelContainer = mount(
<PanelsContainer>
<Panel>{testComponentA}</Panel>
<Panel>{testComponentB}</Panel>
</PanelsContainer>
);
expect(toJson(panelContainer)).toMatchSnapshot();
});

it('should calculate sizes correctly on mouse drags', () => {
// Since this test is not running in the browser we can't expect all of the
// APIs for sizing to be available. The below is a very hacky way of setting
// the DOMElement width so that we have a lightweight test for width calculation
// logic.
const div = mount(<div />);
const proto = (div.find('div').first().getDOMNode() as any).__proto__;
const originalGetBoundingClientRect = proto.getBoundingClientRect;

proto.getBoundingClientRect = spy(() => {
return {
width: 1000,
};
});

try {
// Everything here runs sync.
let widthsCache: number[] = [];
const onWidthChange = (widths: number[]) => {
widthsCache = widths;
};

const panelContainer = mount(
<PanelsContainer onPanelWidthChange={onWidthChange}>
<Panel initialWidth={50}>{testComponentA}</Panel>
<Panel initialWidth={50}>{testComponentB}</Panel>
</PanelsContainer>
);

const resizer = panelContainer.find(`[data-test-subj~="splitPanelResizer"]`).first();

resizer.simulate('mousedown', { clientX: 0 });
resizer.simulate('mousemove', { clientX: 250 });
resizer.simulate('mouseup');

panelContainer.update();

expect(widthsCache).toEqual([125, 75]);
} finally {
proto.getBoundingClientRect = originalGetBoundingClientRect;
}
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export { usePanelContext, PanelContextProvider } from './split_panel_context';
export { PanelRegistry } from './split_panel_registry';
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { createContext, useContext } from 'react';
import { PanelRegistry } from './split_panel_registry';

const PanelContext = createContext({ registry: new PanelRegistry() });

interface ContextProps {
children: JSX.Element;
registry: PanelRegistry;
}

export function PanelContextProvider({ children, registry }: ContextProps) {
return <PanelContext.Provider value={{ registry }}>{children}</PanelContext.Provider>;
}

export const usePanelContext = () => {
const context = useContext(PanelContext);
if (context === undefined) {
throw new Error('usePanelContext must be used within a <PanelContextProvider />');
}
return context;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export interface PanelController {
setWidth: (percent: number) => void;
getWidth: () => number;
width: number;
}

export class PanelRegistry {
private panels: PanelController[] = [];

registerPanel(panel: PanelController) {
this.panels.push(panel);
}

getPanels() {
return this.panels;
}
}

0 comments on commit d50efb2

Please sign in to comment.