Add NavLink, NavButton components
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { FunctionComponentFactory } from 'react';
|
||||
import { NavButton } from './NavButton';
|
||||
import {
|
||||
MemoryRouter,
|
||||
Route,
|
||||
useLocation,
|
||||
NavLink as RouterNavLink,
|
||||
} from 'react-router-dom';
|
||||
import { createRouteRef } from '@backstage/core-api';
|
||||
|
||||
const Location = () => {
|
||||
const location = useLocation();
|
||||
return <pre>Current location: {location.pathname}</pre>;
|
||||
};
|
||||
|
||||
export default {
|
||||
title: 'NavButton',
|
||||
component: NavButton,
|
||||
decorators: [
|
||||
(storyFn: FunctionComponentFactory<{}>) => (
|
||||
<MemoryRouter>
|
||||
<div>
|
||||
<div>
|
||||
<Location />
|
||||
</div>
|
||||
{storyFn()}
|
||||
</div>
|
||||
</MemoryRouter>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const Default = () => {
|
||||
const routeRef = createRouteRef({
|
||||
icon: () => null,
|
||||
path: '/hello',
|
||||
title: 'Hi there!',
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavButton to={routeRef.path}>This button</NavButton> will utilise
|
||||
the react-router MemoryRouter's navigation
|
||||
<Route path={routeRef.path}>
|
||||
<h1>{routeRef.title}</h1>
|
||||
</Route>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const PassProps = () => {
|
||||
const routeRef = createRouteRef({
|
||||
icon: () => null,
|
||||
path: '/hello',
|
||||
title: 'Hi there!',
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavButton
|
||||
to={routeRef.path}
|
||||
/** react-router-dom related prop */
|
||||
component={RouterNavLink}
|
||||
/** material-ui related prop */
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
>
|
||||
This link
|
||||
</NavButton>
|
||||
has props for both material-ui's component as well as for
|
||||
react-router-dom's
|
||||
<Route path={routeRef.path}>
|
||||
<h1>{routeRef.title}</h1>
|
||||
</Route>
|
||||
</>
|
||||
);
|
||||
};
|
||||
PassProps.story = {
|
||||
name: `Accepts material-ui Button's and react-router-dom Link's props`,
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { NavButton } from './NavButton';
|
||||
import { MemoryRouter, Route } from 'react-router';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
describe('<NavButton />', () => {
|
||||
it('navigates using react-router', async () => {
|
||||
const testString = 'This is test string';
|
||||
const buttonLabel = 'Navigate!';
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
<MemoryRouter>
|
||||
<NavButton to="/test">{buttonLabel}</NavButton>
|
||||
<Route path="/test">{testString}</Route>{' '}
|
||||
</MemoryRouter>,
|
||||
),
|
||||
);
|
||||
expect(() => getByText(testString)).toThrow();
|
||||
await act(async () => fireEvent.click(getByText(buttonLabel)));
|
||||
expect(getByText(testString)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ComponentProps } from 'react';
|
||||
import { Button } from '@material-ui/core';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
|
||||
type Props = ComponentProps<typeof Button> & ComponentProps<typeof RouterLink>;
|
||||
|
||||
/**
|
||||
* Thin wrapper on top of material-ui's Button component
|
||||
* Makes the Button to utilise react-router
|
||||
*/
|
||||
export const NavButton = React.forwardRef<any, Props>((props, ref) => (
|
||||
<Button ref={ref} component={RouterLink} {...props} />
|
||||
));
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { NavButton } from './NavButton';
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { FunctionComponentFactory } from 'react';
|
||||
import { NavLink } from './NavLink';
|
||||
import {
|
||||
MemoryRouter,
|
||||
Route,
|
||||
useLocation,
|
||||
NavLink as RouterNavLink,
|
||||
} from 'react-router-dom';
|
||||
import { createRouteRef } from '@backstage/core-api';
|
||||
|
||||
const Location = () => {
|
||||
const location = useLocation();
|
||||
return <pre>Current location: {location.pathname}</pre>;
|
||||
};
|
||||
|
||||
export default {
|
||||
title: 'NavLink',
|
||||
component: NavLink,
|
||||
decorators: [
|
||||
(storyFn: FunctionComponentFactory<{}>) => (
|
||||
<MemoryRouter>
|
||||
<div>
|
||||
<div>
|
||||
<Location />
|
||||
</div>
|
||||
{storyFn()}
|
||||
</div>
|
||||
</MemoryRouter>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const Default = () => {
|
||||
const routeRef = createRouteRef({
|
||||
icon: () => null,
|
||||
path: '/hello',
|
||||
title: 'Hi there!',
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavLink to={routeRef.path}>This link</NavLink> will utilise the
|
||||
react-router MemoryRouter's navigation
|
||||
<Route path={routeRef.path}>
|
||||
<h1>{routeRef.title}</h1>
|
||||
</Route>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const PassProps = () => {
|
||||
const routeRef = createRouteRef({
|
||||
icon: () => null,
|
||||
path: '/hello',
|
||||
title: 'Hi there!',
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavLink
|
||||
to={routeRef.path}
|
||||
/** react-router-dom related prop */
|
||||
component={RouterNavLink}
|
||||
/** material-ui related prop */
|
||||
color="secondary"
|
||||
>
|
||||
This link
|
||||
</NavLink>
|
||||
has props for both material-ui's component as well as for
|
||||
react-router-dom's
|
||||
<Route path={routeRef.path}>
|
||||
<h1>{routeRef.title}</h1>
|
||||
</Route>
|
||||
</>
|
||||
);
|
||||
};
|
||||
PassProps.story = {
|
||||
name: `Accepts material-ui Link's and react-router-dom Link's props`,
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { NavLink } from './NavLink';
|
||||
import { MemoryRouter, Route } from 'react-router';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
describe('<NavLink />', () => {
|
||||
it('navigates using react-router', async () => {
|
||||
const testString = 'This is test string';
|
||||
const linkText = 'Navigate!';
|
||||
const { getByText } = render(
|
||||
wrapInTestApp(
|
||||
<MemoryRouter>
|
||||
<NavLink to="/test">{linkText}</NavLink>
|
||||
<Route path="/test">{testString}</Route>{' '}
|
||||
</MemoryRouter>,
|
||||
),
|
||||
);
|
||||
expect(() => getByText(testString)).toThrow();
|
||||
await act(async () => fireEvent.click(getByText(linkText)));
|
||||
expect(getByText(testString)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ComponentProps } from 'react';
|
||||
import { Link } from '@material-ui/core';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
|
||||
type Props = ComponentProps<typeof Link> & ComponentProps<typeof RouterLink>;
|
||||
|
||||
/**
|
||||
* Thin wrapper on top of material-ui's Link component
|
||||
* Makes the Link to utilise react-router
|
||||
*/
|
||||
export const NavLink = React.forwardRef<any, Props>((props, ref) => (
|
||||
<Link ref={ref} component={RouterLink} {...props} />
|
||||
));
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { NavLink } from './NavLink';
|
||||
@@ -38,4 +38,6 @@ export { default as StructuredMetadataTable } from './components/StructuredMetad
|
||||
export { default as TrendLine } from './components/TrendLine';
|
||||
export { FeatureCalloutCircular } from './components/FeatureDiscovery/FeatureCalloutCircular';
|
||||
export * from './components/Status';
|
||||
export * from './components/NavButton';
|
||||
export * from './components/NavLink';
|
||||
export { default as WarningPanel } from './components/WarningPanel';
|
||||
|
||||
Reference in New Issue
Block a user