mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Changed the splitter for a EUI flyout (#26353)
* Changed the splitter for a EUI flyout * Removed the splitter from the package.json and the HTML * Removed all of the splitter specific panels * Integrated the flyout into the project * Added a absolute positioned button with vertical text called TIMELINE on the right side of the browser * Used mouseover event to trigger the button (for now) ... clickable coming next * Implemented a bit of a overlay to widen the mouseover target more than just the button would have * Styled the button to look more like a tab * Used react setState for toggling between the states of close and open (for now, redux in another PR will happen) * Used older style React class but pulled all the methods I could out to make them as pure as I could * Wrote unit tests which test the rendering, pure functions, and the two class functions * https://github.com/elastic/ingest-dev/issues/108
This commit is contained in:
parent
afe82e2054
commit
a7b36ad9f2
9 changed files with 338 additions and 128 deletions
|
@ -12,7 +12,6 @@
|
|||
"@types/lodash": "^4.14.110"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.10",
|
||||
"react-split-pane": "^0.1.84"
|
||||
"lodash": "^4.17.10"
|
||||
}
|
||||
}
|
||||
|
|
184
x-pack/plugins/secops/public/components/page/flyout.test.tsx
Normal file
184
x-pack/plugins/secops/public/components/page/flyout.test.tsx
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { mount } from 'enzyme';
|
||||
import * as React from 'react';
|
||||
import { closeFlyout, Flyout, FlyoutButton, FlyoutPane, openFlyout, showFlyout } from './flyout';
|
||||
|
||||
describe('Flyout', () => {
|
||||
describe('rendering', () => {
|
||||
test('it renders the default flyout state as a button', () => {
|
||||
const wrapper = mount(<Flyout />);
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutButton"]')
|
||||
.first()
|
||||
.text()
|
||||
).toContain('T I M E L I N E');
|
||||
});
|
||||
|
||||
test('it does NOT render the title element when the default flyout state is a button', () => {
|
||||
const wrapper = mount(<Flyout />);
|
||||
expect(wrapper.find('[data-test-subj="flyoutTitle"]').exists()).toEqual(false);
|
||||
});
|
||||
|
||||
test('it renders the title element when its state is set to flyout is true', () => {
|
||||
const wrapper = mount(<Flyout />).setState({ isFlyoutVisible: true });
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutTitle"]')
|
||||
.first()
|
||||
.text()
|
||||
).toContain('Timeline');
|
||||
});
|
||||
|
||||
test('it does NOT render the fly out button when its state is set to flyout is true', () => {
|
||||
const wrapper = mount(<Flyout />).setState({ isFlyoutVisible: true });
|
||||
expect(wrapper.find('[data-test-subj="flyoutButton"]').exists()).toEqual(false);
|
||||
});
|
||||
|
||||
test('it renders children elements when its state is set to flyout is true', () => {
|
||||
const wrapper = mount(
|
||||
<Flyout>
|
||||
<p>I am a child of flyout</p>
|
||||
</Flyout>
|
||||
).setState({ isFlyoutVisible: true });
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutChildren"]')
|
||||
.first()
|
||||
.text()
|
||||
).toContain('I am a child of flyout');
|
||||
});
|
||||
|
||||
test('should call the onOpen when the mouse is entered for rendering', () => {
|
||||
const openMock = jest.fn();
|
||||
const wrapper = mount<Flyout>(<Flyout />);
|
||||
wrapper.instance().onOpen = openMock;
|
||||
wrapper.instance().forceUpdate();
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutOverlay"]')
|
||||
.first()
|
||||
.simulate('mouseenter');
|
||||
|
||||
expect(openMock).toBeCalled();
|
||||
});
|
||||
|
||||
test('should call the onClose when the close button is clicked', () => {
|
||||
const closeMock = jest.fn();
|
||||
const wrapper = mount<Flyout>(<Flyout />).setState({ isFlyoutVisible: true });
|
||||
wrapper.instance().onClose = closeMock;
|
||||
wrapper.instance().forceUpdate();
|
||||
wrapper
|
||||
.find('[data-test-subj="flyout"] button')
|
||||
.first()
|
||||
.simulate('click');
|
||||
|
||||
expect(closeMock).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('showFlyout', () => {
|
||||
test('should set a state to true when true is passed as an argument', () => {
|
||||
const mockSetState = jest.fn();
|
||||
showFlyout(true, mockSetState);
|
||||
expect(mockSetState).toBeCalledWith({ isFlyoutVisible: true });
|
||||
});
|
||||
|
||||
test('should set a state to false when false is passed as an argument', () => {
|
||||
const mockSetState = jest.fn();
|
||||
showFlyout(false, mockSetState);
|
||||
expect(mockSetState).toBeCalledWith({ isFlyoutVisible: false });
|
||||
});
|
||||
});
|
||||
|
||||
describe('closeFlyout', () => {
|
||||
test('should set a state to false when false is passed as an argument', () => {
|
||||
const mockSetState = jest.fn();
|
||||
closeFlyout(mockSetState);
|
||||
expect(mockSetState).toBeCalledWith({ isFlyoutVisible: false });
|
||||
});
|
||||
});
|
||||
|
||||
describe('openFlyout', () => {
|
||||
test('should set a state to true when true is passed as an argument', () => {
|
||||
const mockSetState = jest.fn();
|
||||
openFlyout(mockSetState);
|
||||
expect(mockSetState).toBeCalledWith({ isFlyoutVisible: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('FlyoutPane', () => {
|
||||
test('should return the flyout element with a title', () => {
|
||||
const closeMock = jest.fn();
|
||||
const wrapper = mount(
|
||||
<FlyoutPane onClose={closeMock}>
|
||||
<span>I am a child of flyout</span>,
|
||||
</FlyoutPane>
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutTitle"]')
|
||||
.first()
|
||||
.text()
|
||||
).toContain('Timeline');
|
||||
});
|
||||
|
||||
test('should return the flyout element with children', () => {
|
||||
const closeMock = jest.fn();
|
||||
const wrapper = mount(
|
||||
<FlyoutPane onClose={closeMock}>
|
||||
<span>I am a mock child</span>,
|
||||
</FlyoutPane>
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutChildren"]')
|
||||
.first()
|
||||
.text()
|
||||
).toContain('I am a mock child');
|
||||
});
|
||||
|
||||
test('should call the onClose when the close button is clicked', () => {
|
||||
const closeMock = jest.fn();
|
||||
const wrapper = mount(
|
||||
<FlyoutPane onClose={closeMock}>
|
||||
<span>I am a mock child</span>,
|
||||
</FlyoutPane>
|
||||
);
|
||||
wrapper
|
||||
.find('[data-test-subj="flyout"] button')
|
||||
.first()
|
||||
.simulate('click');
|
||||
|
||||
expect(closeMock).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('showFlyoutButton', () => {
|
||||
test('should return the flyout button with text', () => {
|
||||
const openMock = jest.fn();
|
||||
const wrapper = mount(<FlyoutButton onOpen={openMock} />);
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutButton"]')
|
||||
.first()
|
||||
.text()
|
||||
).toContain('T I M E L I N E');
|
||||
});
|
||||
|
||||
test('should call the onOpen when the mouse is entered', () => {
|
||||
const openMock = jest.fn();
|
||||
const wrapper = mount(<FlyoutButton onOpen={openMock} />);
|
||||
wrapper
|
||||
.find('[data-test-subj="flyoutOverlay"]')
|
||||
.first()
|
||||
.simulate('mouseenter');
|
||||
|
||||
expect(openMock).toBeCalled();
|
||||
});
|
||||
});
|
||||
});
|
124
x-pack/plugins/secops/public/components/page/flyout.tsx
Normal file
124
x-pack/plugins/secops/public/components/page/flyout.tsx
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiFlyout,
|
||||
EuiFlyoutBody,
|
||||
EuiFlyoutHeader,
|
||||
EuiPanel,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import * as React from 'react';
|
||||
import { pure } from 'recompose';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const Overlay = styled.div`
|
||||
position: absolute;
|
||||
top: 15%;
|
||||
right: 0%;
|
||||
width: 30px;
|
||||
z-index: 1;
|
||||
height: 60%;
|
||||
`;
|
||||
|
||||
export const Button = styled(EuiPanel)`
|
||||
padding: 10px 0 10px 0;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
right: 5%;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
border-top: 1px solid #c5c5c5;
|
||||
border-bottom: 1px solid #c5c5c5;
|
||||
border-left: 1px solid #c5c5c5;
|
||||
border-radius: 6px 0 0 6px;
|
||||
box-shadow: 0 3px 3px -1px rgba(173, 173, 173, 0.5), 0 5px 7px -2px rgba(173, 173, 173, 0.5);
|
||||
background-color: #fff;
|
||||
`;
|
||||
|
||||
export const Text = styled(EuiText)`
|
||||
width: 12px;
|
||||
z-index: 3;
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
isFlyoutVisible?: boolean;
|
||||
}
|
||||
|
||||
interface State {
|
||||
isFlyoutVisible: boolean;
|
||||
}
|
||||
|
||||
type SetState = (opts: State) => void;
|
||||
|
||||
export const showFlyout = (isFlyoutVisible: boolean, setState: SetState) =>
|
||||
setState({ isFlyoutVisible });
|
||||
|
||||
export const closeFlyout = (setState: SetState) => showFlyout(false, setState);
|
||||
|
||||
export const openFlyout = (setState: SetState) => showFlyout(true, setState);
|
||||
|
||||
interface FlyoutPaneProps {
|
||||
onClose: () => void;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const FlyoutPane = pure(({ onClose, children }: FlyoutPaneProps) => (
|
||||
<EuiFlyout onClose={onClose} aria-labelledby="flyoutTitle" data-test-subj="flyout">
|
||||
<EuiFlyoutHeader hasBorder>
|
||||
<EuiTitle size="m">
|
||||
<h2 data-test-subj="flyoutTitle" id="flyoutTitle">
|
||||
Timeline
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody data-test-subj="flyoutChildren">{children}</EuiFlyoutBody>
|
||||
</EuiFlyout>
|
||||
));
|
||||
|
||||
interface FlyoutButtonProps {
|
||||
onOpen: () => void;
|
||||
}
|
||||
|
||||
export const FlyoutButton = pure(({ onOpen }: FlyoutButtonProps) => (
|
||||
<Overlay data-test-subj="flyoutOverlay" onMouseEnter={onOpen}>
|
||||
<Button>
|
||||
<Text data-test-subj="flyoutButton">T I M E L I N E</Text>
|
||||
</Button>
|
||||
</Overlay>
|
||||
));
|
||||
|
||||
export class Flyout extends React.PureComponent<Props, State> {
|
||||
public readonly state = {
|
||||
isFlyoutVisible: this.props.isFlyoutVisible ? this.props.isFlyoutVisible : false,
|
||||
};
|
||||
|
||||
public render = () =>
|
||||
this.state.isFlyoutVisible ? (
|
||||
<FlyoutPane onClose={this.onClose}>{this.props.children}</FlyoutPane>
|
||||
) : (
|
||||
<FlyoutButton onOpen={this.onOpen} />
|
||||
);
|
||||
|
||||
/**
|
||||
* Provides stable instance reference for avoiding re-renders.
|
||||
* setState.bind is required although this is a ES2017 function since setState
|
||||
* is impure and calls other functions within this class.
|
||||
*/
|
||||
public onClose = () => closeFlyout(this.setState.bind(this));
|
||||
|
||||
/**
|
||||
* Provides stable instance reference for avoiding re-renders.
|
||||
* setState.bind is required although this is a ES2017 function since setState
|
||||
* is impure and calls other functions within this class.
|
||||
*/
|
||||
public onOpen = () => openFlyout(this.setState.bind(this));
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import { EuiPage } from '@elastic/eui';
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const PageContainer = styled.div`
|
||||
|
@ -65,17 +64,15 @@ export const PaneScrollContainer = styled.div`
|
|||
overflow-y: scroll;
|
||||
`;
|
||||
|
||||
export const Pane1 = styled.div`
|
||||
export const Pane = styled.div`
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
/** For use with the `SplitPane` `pane1Style` prop */
|
||||
export const Pane1Style: React.CSSProperties = {
|
||||
height: '100%',
|
||||
marginTop: '5px',
|
||||
};
|
||||
export const PaneHeader = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
export const Pane1FlexContent = styled.div`
|
||||
display: flex;
|
||||
|
@ -83,32 +80,3 @@ export const Pane1FlexContent = styled.div`
|
|||
flex-wrap: wrap;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
export const Pane1Header = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
export const Pane2 = styled.div`
|
||||
height: 100%;
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
/** For use with the `SplitPane` `pane2Style` prop */
|
||||
export const Pane2Style: React.CSSProperties = {
|
||||
height: '100%',
|
||||
};
|
||||
|
||||
export const Pane2TimelineContainer = styled.div`
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
/** For use with the `SplitPane` `resizerStyle` prop */
|
||||
export const ResizerStyle: React.CSSProperties = {
|
||||
border: '5px solid #909AA1',
|
||||
backgroundClip: 'padding-box',
|
||||
cursor: 'col-resize',
|
||||
margin: '5px',
|
||||
zIndex: 1,
|
||||
};
|
||||
|
|
|
@ -14,24 +14,19 @@ import * as React from 'react';
|
|||
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||
import { pure } from 'recompose';
|
||||
|
||||
import SplitPane from 'react-split-pane';
|
||||
import { LinkToPage } from '../../components/link_to';
|
||||
import {
|
||||
PageContainer,
|
||||
PageContent,
|
||||
PageHeader,
|
||||
Pane1,
|
||||
Pane1Header,
|
||||
Pane1Style,
|
||||
Pane2,
|
||||
Pane2Style,
|
||||
Pane2TimelineContainer,
|
||||
Pane,
|
||||
PaneHeader,
|
||||
PaneScrollContainer,
|
||||
ResizerStyle,
|
||||
SubHeader,
|
||||
SubHeaderDatePicker,
|
||||
} from '../../components/page';
|
||||
import { DatePicker } from '../../components/page/date_picker';
|
||||
import { Flyout } from '../../components/page/flyout';
|
||||
import { Footer } from '../../components/page/footer';
|
||||
import { Navigation } from '../../components/page/navigation';
|
||||
import { StatefulTimeline } from '../../components/timeline';
|
||||
|
@ -45,6 +40,9 @@ const maxTimelineWidth = 1125;
|
|||
|
||||
export const HomePage = pure(() => (
|
||||
<PageContainer data-test-subj="pageContainer">
|
||||
<Flyout>
|
||||
<StatefulTimeline id="timeline" headers={headers} width={maxTimelineWidth} />
|
||||
</Flyout>
|
||||
<PageHeader data-test-subj="pageHeader">
|
||||
<Navigation data-test-subj="navigation" />
|
||||
</PageHeader>
|
||||
|
@ -55,41 +53,21 @@ export const HomePage = pure(() => (
|
|||
</SubHeaderDatePicker>
|
||||
<EuiHorizontalRule margin="none" />
|
||||
</SubHeader>
|
||||
|
||||
<SplitPane
|
||||
data-test-subj="splitPane"
|
||||
split="vertical"
|
||||
defaultSize="75%"
|
||||
primary="second"
|
||||
pane1Style={Pane1Style}
|
||||
pane2Style={{
|
||||
...Pane2Style,
|
||||
maxWidth: `${maxTimelineWidth}px`,
|
||||
}}
|
||||
resizerStyle={ResizerStyle}
|
||||
>
|
||||
<Pane1 data-test-subj="pane1">
|
||||
<Pane1Header data-test-subj="pane1Header">
|
||||
<EuiSearchBar onChange={noop} />
|
||||
</Pane1Header>
|
||||
<PaneScrollContainer data-test-subj="pane1ScrollContainer">
|
||||
<Switch>
|
||||
<Redirect from="/" exact={true} to="/overview" />
|
||||
<Route path="/overview" component={Overview} />
|
||||
<Route path="/hosts" component={Hosts} />
|
||||
<Route path="/network" component={Network} />
|
||||
<Route path="/link-to" component={LinkToPage} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</PaneScrollContainer>
|
||||
</Pane1>
|
||||
|
||||
<Pane2 data-test-subj="pane2">
|
||||
<Pane2TimelineContainer data-test-subj="pane2TimelineContainer">
|
||||
<StatefulTimeline id="pane2-timeline" headers={headers} width={maxTimelineWidth} />
|
||||
</Pane2TimelineContainer>
|
||||
</Pane2>
|
||||
</SplitPane>
|
||||
<Pane data-test-subj="pane">
|
||||
<PaneHeader data-test-subj="paneHeader">
|
||||
<EuiSearchBar onChange={noop} />
|
||||
</PaneHeader>
|
||||
<PaneScrollContainer data-test-subj="pane1ScrollContainer">
|
||||
<Switch>
|
||||
<Redirect from="/" exact={true} to="/overview" />
|
||||
<Route path="/overview" component={Overview} />
|
||||
<Route path="/hosts" component={Hosts} />
|
||||
<Route path="/network" component={Network} />
|
||||
<Route path="/link-to" component={LinkToPage} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</PaneScrollContainer>
|
||||
</Pane>
|
||||
</PageContent>
|
||||
<Footer />
|
||||
</PageContainer>
|
||||
|
|
|
@ -68,7 +68,7 @@ export const Hosts = connect()(
|
|||
title="Events"
|
||||
/>
|
||||
</VisualizationPlaceholder>
|
||||
<Placeholders timelineId="pane2-timeline" count={8} myRoute="Hosts" />
|
||||
<Placeholders timelineId="timeline" count={8} myRoute="Hosts" />
|
||||
</Pane1FlexContent>
|
||||
)}
|
||||
</EventsQuery>
|
||||
|
@ -98,7 +98,7 @@ const getEventsColumns = (dispatch: Dispatch) => [
|
|||
onClick={() => {
|
||||
dispatch(
|
||||
timelineActions.addProvider({
|
||||
id: 'pane2-timeline',
|
||||
id: 'timeline',
|
||||
provider: {
|
||||
enabled: true,
|
||||
id: `id-${hostName}`,
|
||||
|
|
|
@ -12,6 +12,6 @@ import { Placeholders } from '../../components/visualization_placeholder';
|
|||
|
||||
export const Network = pure(() => (
|
||||
<Pane1FlexContent>
|
||||
<Placeholders timelineId="pane2-timeline" count={10} myRoute="Network" />
|
||||
<Placeholders timelineId="timeline" count={10} myRoute="Network" />
|
||||
</Pane1FlexContent>
|
||||
));
|
||||
|
|
|
@ -12,6 +12,6 @@ import { Placeholders } from '../../components/visualization_placeholder';
|
|||
|
||||
export const Overview = pure(() => (
|
||||
<Pane1FlexContent>
|
||||
<Placeholders timelineId="pane2-timeline" count={10} myRoute="Overview" />
|
||||
<Placeholders timelineId="timeline" count={10} myRoute="Overview" />
|
||||
</Pane1FlexContent>
|
||||
));
|
||||
|
|
43
yarn.lock
43
yarn.lock
|
@ -4189,11 +4189,6 @@ bounce@1.x.x:
|
|||
boom "7.x.x"
|
||||
hoek "5.x.x"
|
||||
|
||||
bowser@^1.7.3:
|
||||
version "1.9.4"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a"
|
||||
integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==
|
||||
|
||||
boxen@1.3.0, boxen@^1.2.1, boxen@^1.2.2:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
|
||||
|
@ -6206,14 +6201,6 @@ css-color-names@0.0.4:
|
|||
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
|
||||
integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
|
||||
|
||||
css-in-js-utils@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99"
|
||||
integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.2"
|
||||
isobject "^3.0.1"
|
||||
|
||||
css-loader@0.28.7:
|
||||
version "0.28.7"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b"
|
||||
|
@ -11023,11 +11010,6 @@ humps@2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/humps/-/humps-2.0.1.tgz#dd02ea6081bd0568dc5d073184463957ba9ef9aa"
|
||||
integrity sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao=
|
||||
|
||||
hyphenate-style-name@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
|
||||
integrity sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=
|
||||
|
||||
icalendar@0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/icalendar/-/icalendar-0.7.1.tgz#d0d3486795f8f1c5cf4f8cafac081b4b4e7a32ae"
|
||||
|
@ -11223,14 +11205,6 @@ ini@^1.3.4, ini@~1.3.0:
|
|||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
||||
|
||||
inline-style-prefixer@^3.0.6:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz#8551b8e5b4d573244e66a34b04f7d32076a2b534"
|
||||
integrity sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=
|
||||
dependencies:
|
||||
bowser "^1.7.3"
|
||||
css-in-js-utils "^2.0.0"
|
||||
|
||||
inline-style@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/inline-style/-/inline-style-2.0.0.tgz#2fa9cf624596a8109355b925094e138bbd5ea29b"
|
||||
|
@ -18017,16 +17991,6 @@ react-sizeme@^2.3.6:
|
|||
invariant "^2.2.2"
|
||||
lodash "^4.17.4"
|
||||
|
||||
react-split-pane@^0.1.84:
|
||||
version "0.1.84"
|
||||
resolved "https://registry.yarnpkg.com/react-split-pane/-/react-split-pane-0.1.84.tgz#b9c1499cbc40b09cf29953ee6f5ff1039d31906e"
|
||||
integrity sha512-rso1dRAXX/WETyqF5C0fomIYzpF71Nothfr1R7pFkrJCPVJ20ok2e6wqF+JvUTyE/meiBvsbNPT1loZjyU+53w==
|
||||
dependencies:
|
||||
inline-style-prefixer "^3.0.6"
|
||||
prop-types "^15.5.10"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
react-style-proptype "^3.0.0"
|
||||
|
||||
react-sticky@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-sticky/-/react-sticky-6.0.1.tgz#356988bdcc6fc8cd2d89746d2302edce67d86687"
|
||||
|
@ -18035,13 +17999,6 @@ react-sticky@^6.0.1:
|
|||
prop-types "^15.5.8"
|
||||
raf "^3.3.0"
|
||||
|
||||
react-style-proptype@^3.0.0:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/react-style-proptype/-/react-style-proptype-3.2.2.tgz#d8e998e62ce79ec35b087252b90f19f1c33968a0"
|
||||
integrity sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==
|
||||
dependencies:
|
||||
prop-types "^15.5.4"
|
||||
|
||||
react-syntax-highlighter@^5.7.0:
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-5.8.0.tgz#a220c010fd0641751d93532509ba7159cc3a4383"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue