diff --git a/packages/core/src/components/ProgressBars/ProgressCard.tsx b/packages/core/src/components/ProgressBars/ProgressCard.tsx
index 1964f382e9..dc3ee7aa35 100644
--- a/packages/core/src/components/ProgressBars/ProgressCard.tsx
+++ b/packages/core/src/components/ProgressBars/ProgressCard.tsx
@@ -16,9 +16,8 @@
import React, { FC } from 'react';
import { makeStyles } from '@material-ui/core';
-
import InfoCard from 'layout/InfoCard';
-import { Props as BottomLinkProps } from 'layout/InfoCard/BottomLink';
+import { Props as BottomLinkProps } from '../layout/BottomLink';
import CircleProgress from './CircleProgress';
type Props = {
diff --git a/packages/core/src/components/SortableTable.js b/packages/core/src/components/SortableTable.js
index e04b844048..ab4e1af2de 100644
--- a/packages/core/src/components/SortableTable.js
+++ b/packages/core/src/components/SortableTable.js
@@ -171,7 +171,7 @@ const DataTableRow = pure(({ row, columns, handleRowClick, style }) => {
* @example
* render {
* const data = [
- * { id: 'buffalos', amount: 1, status: , statusValue: 2 }
+ * { id: 'buffalos', amount: 1, status: , statusValue: 2 },
* { id: 'milk', amount: 3, status: , statusValue: 1 }
* ];
* const columns = [
diff --git a/packages/core/src/components/SortableTable.stories.tsx b/packages/core/src/components/SortableTable.stories.tsx
new file mode 100644
index 0000000000..c534457d53
--- /dev/null
+++ b/packages/core/src/components/SortableTable.stories.tsx
@@ -0,0 +1,57 @@
+/*
+ * 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 { StatusError, StatusOK, StatusWarning } from './Status';
+import SortableTable from './SortableTable';
+
+export default {
+ title: 'Sortable Table',
+ component: SortableTable,
+};
+const containerStyle = { width: 600, padding: 20 };
+
+const data = [
+ { id: 'buffalos', amount: 1, status: , statusValue: 2 },
+ { id: 'milk', amount: 3, status: , statusValue: 1 },
+ { id: 'cheese', amount: 8, status: , statusValue: 1 },
+ { id: 'bread', amount: 2, status: , statusValue: 0 },
+];
+const columns = [
+ { id: 'id', label: 'ID' },
+ { id: 'amount', disablePadding: false, numeric: true, label: 'AMOUNT' },
+ { id: 'status', label: 'STATUS', sortValue: row => row.statusValue },
+];
+const footerData = [
+ { id: 'total', amount: 4, statusValue: 2, status: },
+];
+
+export const Default = () => (
+
+
+
+);
+
+export const WithFooter = () => (
+
+
+
+);
diff --git a/packages/core/src/components/Status/Status.stories.tsx b/packages/core/src/components/Status/Status.stories.tsx
new file mode 100644
index 0000000000..91ef53d7fe
--- /dev/null
+++ b/packages/core/src/components/Status/Status.stories.tsx
@@ -0,0 +1,67 @@
+/*
+ * 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 {
+ StatusError,
+ StatusFailed,
+ StatusNA,
+ StatusOK,
+ StatusPending,
+ StatusRunning,
+ StatusWarning,
+} from './Status';
+
+export default {
+ title: 'Status',
+ component: StatusOK,
+};
+
+export const statusOK = () => (
+ <>
+ Status OK
+ >
+);
+export const statusWarning = () => (
+ <>
+ Status Warning
+ >
+);
+export const statusError = () => (
+ <>
+ Status Error
+ >
+);
+export const statusFailed = () => (
+ <>
+ Status Failed
+ >
+);
+export const statusPending = () => (
+ <>
+ Status Pending
+ >
+);
+export const statusRunning = () => (
+ <>
+ Status Running
+ >
+);
+export const statusNA = () => (
+ <>
+ Status NA
+ >
+);
diff --git a/packages/core/src/components/WarningPanel/WarningPanel.js b/packages/core/src/components/WarningPanel/WarningPanel.js
new file mode 100644
index 0000000000..679f7511d8
--- /dev/null
+++ b/packages/core/src/components/WarningPanel/WarningPanel.js
@@ -0,0 +1,80 @@
+/*
+ * 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, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { Typography, withStyles } from '@material-ui/core';
+import ErrorOutline from '@material-ui/icons/ErrorOutline';
+
+const errorOutlineStyles = theme => ({
+ root: {
+ marginRight: theme.spacing(1),
+ fill: theme.palette.warningText,
+ },
+});
+const ErrorOutlineStyled = withStyles(errorOutlineStyles)(ErrorOutline);
+
+const styles = theme => ({
+ message: {
+ display: 'flex',
+ flexDirection: 'column',
+ padding: theme.spacing(1.5),
+ backgroundColor: theme.palette.warningBackground,
+ color: theme.palette.warningText,
+ verticalAlign: 'middle',
+ },
+ header: {
+ display: 'flex',
+ flexDirection: 'row',
+ marginBottom: theme.spacing(1),
+ },
+ headerText: {
+ color: theme.palette.warningText,
+ },
+ messageText: {
+ color: theme.palette.warningText,
+ },
+});
+
+/**
+ * WarningPanel. Show a user friendly error message to a user similar to ErrorPanel except that the warning panel
+ * only shows the warning message to the user
+ */
+class WarningPanel extends Component {
+ static propTypes = {
+ message: PropTypes.node.isRequired,
+ };
+
+ render() {
+ const { classes, title, message, children } = this.props;
+ return (
+
+
+
+
+ {title}
+
+
+ {message && (
+ {message}
+ )}
+ {children}
+
+ );
+ }
+}
+
+export default withStyles(styles)(WarningPanel);
diff --git a/packages/core/src/components/WarningPanel/WarningPanel.stories.tsx b/packages/core/src/components/WarningPanel/WarningPanel.stories.tsx
new file mode 100644
index 0000000000..2fd5395db5
--- /dev/null
+++ b/packages/core/src/components/WarningPanel/WarningPanel.stories.tsx
@@ -0,0 +1,45 @@
+/*
+ * 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 WarningPanel from '.';
+import { Link, Button } from '@material-ui/core';
+
+export default {
+ title: 'Warning Panel',
+ component: WarningPanel,
+};
+
+export const Default = () => (
+
+ This example entity is missing something. If this is unexpected, please
+ make sure you have set up everything correctly by following{' '}
+ this guide.
+ >
+ }
+ />
+);
+
+export const Children = () => (
+
+
+
+);
diff --git a/packages/core/src/components/WarningPanel/WarningPanel.test.js b/packages/core/src/components/WarningPanel/WarningPanel.test.js
new file mode 100644
index 0000000000..4094c65a1f
--- /dev/null
+++ b/packages/core/src/components/WarningPanel/WarningPanel.test.js
@@ -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 } from '@testing-library/react';
+import { wrapInThemedTestApp } from '@backstage/test-utils';
+
+import WarningPanel from './WarningPanel';
+
+const minProps = { title: 'Mock title', message: 'Some more info' };
+
+describe('', () => {
+ it('renders without exploding', () => {
+ const { getByText } = render(
+ wrapInThemedTestApp(),
+ );
+ expect(getByText('Mock title')).toBeInTheDocument();
+ });
+
+ it('renders message and children', () => {
+ const { getByText } = render(
+ wrapInThemedTestApp(children),
+ );
+ expect(getByText('Some more info')).toBeInTheDocument();
+ expect(getByText('children')).toBeInTheDocument();
+ });
+});
diff --git a/packages/core/src/components/WarningPanel/index.js b/packages/core/src/components/WarningPanel/index.js
new file mode 100644
index 0000000000..704453fb47
--- /dev/null
+++ b/packages/core/src/components/WarningPanel/index.js
@@ -0,0 +1,16 @@
+/*
+ * 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 { default } from './WarningPanel';
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 40a4bd452e..93288b9b68 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -36,3 +36,4 @@ export { default as SortableTable } from './components/SortableTable';
export { default as StructuredMetadataTable } from './components/StructuredMetadataTable';
export { FeatureCalloutCircular } from './components/FeatureDiscovery/FeatureCalloutCircular';
export * from './components/Status';
+export { default as WarningPanel } from './components/WarningPanel';
diff --git a/packages/core/src/layout/InfoCard/BottomLink.test.tsx b/packages/core/src/layout/BottomLink/BottomLink.test.tsx
similarity index 100%
rename from packages/core/src/layout/InfoCard/BottomLink.test.tsx
rename to packages/core/src/layout/BottomLink/BottomLink.test.tsx
diff --git a/packages/core/src/layout/InfoCard/BottomLink.tsx b/packages/core/src/layout/BottomLink/BottomLink.tsx
similarity index 100%
rename from packages/core/src/layout/InfoCard/BottomLink.tsx
rename to packages/core/src/layout/BottomLink/BottomLink.tsx
index 6721eda0f1..9250685504 100644
--- a/packages/core/src/layout/InfoCard/BottomLink.tsx
+++ b/packages/core/src/layout/BottomLink/BottomLink.tsx
@@ -14,18 +14,18 @@
* limitations under the License.
*/
+import React, { FC } from 'react';
import {
- Divider,
Link,
ListItem,
ListItemIcon,
+ Divider,
ListItemText,
makeStyles,
} from '@material-ui/core';
-import Box from '@material-ui/core/Box';
-import grey from '@material-ui/core/colors/grey';
import ArrowIcon from '@material-ui/icons/ArrowForward';
-import React, { FC } from 'react';
+import grey from '@material-ui/core/colors/grey';
+import Box from '@material-ui/core/Box';
const useStyles = makeStyles(theme => ({
root: {
diff --git a/packages/core/src/layout/BottomLink/index.ts b/packages/core/src/layout/BottomLink/index.ts
new file mode 100644
index 0000000000..5d4845064b
--- /dev/null
+++ b/packages/core/src/layout/BottomLink/index.ts
@@ -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 { default, Props } from './BottomLink';
diff --git a/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.js b/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.js
deleted file mode 100644
index abe0ee8b33..0000000000
--- a/packages/core/src/layout/HeaderLabel/OwnerHeaderLabel.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { Tooltip, Link, withStyles } from '@material-ui/core';
-
-import { StatusError } from 'components/Status';
-import HeaderLabel from './HeaderLabel';
-
-const style = theme => ({
- notVerified: {
- color: theme.palette.status.error,
- borderRadius: 4,
- padding: '3px 6px',
- fontSize: '8pt',
- opacity: 0.8,
- fontWeight: 'bold',
- position: 'relative',
- top: -4,
- backgroundColor: 'pink',
- float: 'right',
- marginLeft: 14,
- },
- label: { float: 'left' },
-});
-
-class OwnerHeaderLabel extends Component {
- static propTypes = {
- owner: PropTypes.object.isRequired,
- };
-
- render() {
- const { owner, classes } = this.props;
- const isBadSquad = owner.type !== 'squad';
-
- const notVerified = isBadSquad && (
-
-
- Squad not
- verified!
-
-
- );
- const label = (
-
-
- {owner.name}
-
-
- );
- return (
- <>
-
- {notVerified}
- >
- );
- }
-}
-
-export default withStyles(style)(OwnerHeaderLabel);
diff --git a/packages/core/src/layout/InfoCard/InfoCard.tsx b/packages/core/src/layout/InfoCard/InfoCard.tsx
index caa5f16513..f3d03d29c8 100644
--- a/packages/core/src/layout/InfoCard/InfoCard.tsx
+++ b/packages/core/src/layout/InfoCard/InfoCard.tsx
@@ -25,7 +25,7 @@ import {
makeStyles,
} from '@material-ui/core';
import ErrorBoundary from 'layout/ErrorBoundary/ErrorBoundary';
-import BottomLink, { Props as BottomLinkProps } from './BottomLink';
+import BottomLink, { Props as BottomLinkProps } from '../BottomLink';
const useStyles = makeStyles(theme => ({
header: {
diff --git a/packages/core/src/layout/Sidebar/Bar.tsx b/packages/core/src/layout/Sidebar/Bar.tsx
index 23ac14b6a4..4cf3db63ab 100644
--- a/packages/core/src/layout/Sidebar/Bar.tsx
+++ b/packages/core/src/layout/Sidebar/Bar.tsx
@@ -18,8 +18,9 @@ import { makeStyles } from '@material-ui/core';
import clsx from 'clsx';
import React, { FC, useRef, useState } from 'react';
import { sidebarConfig, SidebarContext } from './config';
+import { BackstageTheme } from '@backstage/theme';
-const useStyles = makeStyles(theme => ({
+const useStyles = makeStyles(theme => ({
root: {
zIndex: 1000,
position: 'relative',
@@ -35,7 +36,7 @@ const useStyles = makeStyles(theme => ({
top: 0,
bottom: 0,
padding: 0,
- background: '#171717',
+ background: theme.palette.sidebar,
overflowX: 'hidden',
width: sidebarConfig.drawerWidthClosed,
transition: theme.transitions.create('width', {
diff --git a/packages/core/src/layout/TabbedCard/TabbedCard.stories.tsx b/packages/core/src/layout/TabbedCard/TabbedCard.stories.tsx
new file mode 100644
index 0000000000..d670b0b908
--- /dev/null
+++ b/packages/core/src/layout/TabbedCard/TabbedCard.stories.tsx
@@ -0,0 +1,77 @@
+/*
+ * 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, { useState } from 'react';
+import { TabbedCard, CardTab } from '.';
+
+export default {
+ title: 'Tabbed Card',
+ component: TabbedCard,
+};
+
+export const Default = () => {
+ return (
+
+ some content 1
+ some content 2
+ some content 3
+ some content 4
+
+ );
+};
+
+const linkInfo = { title: 'Go to XYZ Location', link: '#' };
+
+export const WithFooterLink = () => {
+ return (
+
+ some content 1
+ some content 2
+ some content 3
+ some content 4
+
+ );
+};
+
+export const WithControlledTabValue = () => {
+ const [selectedTab, setSelectedTab] = useState('one');
+
+ const handleChange = (_ev, newSelectedTab) => setSelectedTab(newSelectedTab);
+
+ return (
+ <>
+ Selected tab is {selectedTab}
+
+
+
+ some content 1
+
+
+ some content 2
+
+
+ some content 3
+
+
+ some content 4
+
+
+ >
+ );
+};
diff --git a/packages/core/src/layout/TabbedCard/TabbedCard.test.tsx b/packages/core/src/layout/TabbedCard/TabbedCard.test.tsx
new file mode 100644
index 0000000000..ceeae8d49d
--- /dev/null
+++ b/packages/core/src/layout/TabbedCard/TabbedCard.test.tsx
@@ -0,0 +1,105 @@
+/*
+ * 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 { TabbedCard, CardTab } from '.';
+
+const minProps = {
+ title: 'Some title',
+ deepLink: {
+ title: 'A deepLink title',
+ link: '/mocked',
+ },
+};
+
+describe('', () => {
+ it('renders without exploding', () => {
+ const rendered = render(
+ wrapInTestApp(
+
+ Test Content
+ Test Content
+ ,
+ ),
+ );
+ expect(rendered.getByText('Some title')).toBeInTheDocument();
+ });
+
+ it('renders a deepLink when prop is set', () => {
+ const rendered = render(
+ wrapInTestApp(
+
+ Test Content
+ Test Content
+ ,
+ ),
+ );
+ expect(rendered.getByText('A deepLink title')).toBeInTheDocument();
+ });
+
+ it('switches tabs when clicking', () => {
+ const rendered = render(
+ wrapInTestApp(
+
+ Test Content 1
+ Test Content 2
+ ,
+ ),
+ );
+ expect(rendered.getByText('Test Content 1')).toBeInTheDocument();
+
+ fireEvent.click(rendered.getByText('Test 2'));
+ expect(rendered.getByText('Test Content 2')).toBeInTheDocument();
+ });
+
+ it('switches tabs when clicking in controlled mode', () => {
+ let selectedTab = 'one';
+
+ const handleTabChange = jest.fn(
+ (_ev, newSelectedTab) => (selectedTab = newSelectedTab),
+ );
+
+ const rendered = render(
+ wrapInTestApp(
+
+
+ Test Content 1
+
+
+ Test Content 2
+
+ ,
+ ),
+ );
+ expect(rendered.getByText('Test Content 1')).toBeInTheDocument();
+
+ fireEvent.click(rendered.getByText('Test 2'));
+ expect(handleTabChange.mock.calls.length).toBe(1);
+ rendered.rerender(
+
+
+ Test Content 1
+
+
+ Test Content 2
+
+ ,
+ );
+ expect(rendered.getByText('Test Content 2')).toBeInTheDocument();
+ });
+});
diff --git a/packages/core/src/layout/TabbedCard/TabbedCard.tsx b/packages/core/src/layout/TabbedCard/TabbedCard.tsx
new file mode 100644
index 0000000000..bd7443e924
--- /dev/null
+++ b/packages/core/src/layout/TabbedCard/TabbedCard.tsx
@@ -0,0 +1,127 @@
+/*
+ * 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, { FC, useState, ReactElement, ReactNode } from 'react';
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ Divider,
+ withStyles,
+ makeStyles,
+ Tabs,
+ Tab,
+ TabProps,
+} from '@material-ui/core';
+import BottomLink, { Props as BottomLinkProps } from '../BottomLink';
+import ErrorBoundary from '../ErrorBoundary/ErrorBoundary';
+
+const useTabsStyles = makeStyles(theme => ({
+ root: {
+ padding: theme.spacing(0, 2, 0, 2.5),
+ minHeight: theme.spacing(3),
+ },
+ indicator: {
+ backgroundColor: theme.palette.info.main,
+ height: theme.spacing(0.3),
+ },
+}));
+
+const BoldHeader = withStyles(theme => ({
+ root: { padding: theme.spacing(2, 2, 2, 2.5), display: 'inline-block' },
+ title: { fontWeight: 700 },
+ subheader: { paddingTop: theme.spacing(1) },
+}))(CardHeader);
+
+type Props = {
+ slackChannel?: string;
+ children?: ReactElement[];
+ onChange?: (event: React.ChangeEvent<{}>, value: number | string) => void;
+ title?: string;
+ value?: number | string;
+ deepLink?: BottomLinkProps;
+};
+
+const TabbedCard: FC = ({
+ slackChannel = '#backstage',
+ children,
+ title,
+ deepLink,
+ value,
+ onChange,
+}) => {
+ const tabsClasses = useTabsStyles();
+ const [selectedIndex, selectIndex] = useState(0);
+
+ const handleChange = onChange
+ ? onChange
+ : (_ev, newSelectedIndex: number) => selectIndex(newSelectedIndex);
+
+ let selectedTabContent: ReactNode;
+ if (!value) {
+ React.Children.map(children, (child, index) => {
+ if (index === selectedIndex) selectedTabContent = child?.props.children;
+ });
+ } else {
+ React.Children.map(children, child => {
+ if (child?.props.value === value)
+ selectedTabContent = child?.props.children;
+ });
+ }
+
+ return (
+
+
+ {title && }
+
+ {children}
+
+
+ {selectedTabContent}
+ {deepLink && }
+
+
+ );
+};
+
+const useCardTabStyles = makeStyles(theme => ({
+ root: {
+ minWidth: theme.spacing(6),
+ minHeight: theme.spacing(3),
+ margin: theme.spacing(0, 2, 0, 0),
+ padding: theme.spacing(0.5, 0, 0.5, 0),
+ textTransform: 'none',
+ },
+ selected: {
+ fontWeight: 'bold',
+ },
+}));
+
+type CardTabProps = TabProps & {
+ children: ReactNode;
+};
+
+const CardTab: FC = ({ children, ...props }) => {
+ const classes = useCardTabStyles();
+
+ return ;
+};
+
+export { TabbedCard, CardTab };
diff --git a/packages/core/src/layout/TabbedCard/index.ts b/packages/core/src/layout/TabbedCard/index.ts
new file mode 100644
index 0000000000..f5019f2451
--- /dev/null
+++ b/packages/core/src/layout/TabbedCard/index.ts
@@ -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 * from './TabbedCard';
diff --git a/packages/storybook/.storybook/config.js b/packages/storybook/.storybook/config.js
new file mode 100644
index 0000000000..b083bc0e9e
--- /dev/null
+++ b/packages/storybook/.storybook/config.js
@@ -0,0 +1,10 @@
+import React from 'react';
+import { addDecorator } from '@storybook/react';
+import { BackstageTheme } from '@backstage/theme';
+import { CssBaseline, ThemeProvider } from '@material-ui/core';
+
+addDecorator(story => (
+
+ {story()}
+
+));
diff --git a/packages/storybook/.storybook/main.js b/packages/storybook/.storybook/main.js
index cf81bf382d..f086fa0d4a 100644
--- a/packages/storybook/.storybook/main.js
+++ b/packages/storybook/.storybook/main.js
@@ -5,7 +5,11 @@ module.exports = {
'../../core/src/layout/**/*.stories.tsx',
'../../core/src/components/**/*.stories.tsx',
],
- addons: ['@storybook/addon-actions', '@storybook/addon-links'],
+ addons: [
+ '@storybook/addon-actions',
+ '@storybook/addon-links',
+ '@storybook/addon-storysource',
+ ],
webpackFinal: async config => {
config.resolve.alias = {
...config.resolve.alias,
diff --git a/packages/storybook/package.json b/packages/storybook/package.json
index 4dbf2990fa..f884da5f07 100644
--- a/packages/storybook/package.json
+++ b/packages/storybook/package.json
@@ -15,6 +15,7 @@
"devDependencies": {
"@storybook/addon-actions": "^5.3.17",
"@storybook/addon-links": "^5.3.17",
+ "@storybook/addon-storysource": "^5.3.18",
"@storybook/addons": "^5.3.17",
"@storybook/react": "^5.3.17"
}
diff --git a/packages/test-utils-core/.npmrc b/packages/test-utils-core/.npmrc
new file mode 100644
index 0000000000..214c29d139
--- /dev/null
+++ b/packages/test-utils-core/.npmrc
@@ -0,0 +1 @@
+registry=https://registry.npmjs.org/
diff --git a/packages/test-utils-core/README.md b/packages/test-utils-core/README.md
new file mode 100644
index 0000000000..b99250857d
--- /dev/null
+++ b/packages/test-utils-core/README.md
@@ -0,0 +1,15 @@
+# @backstage/test-utils-core
+
+This package provides utilities for testing the Backstage core packages.
+
+## Installation
+
+This package should not be used directly, use `@backstage/test-utils` instead. All exports from this
+package are re-exported by `@backstage/test-utils`.
+
+The reason this package exists is to allow the Backstage core packages to use the testing utils exposed in this package. Since `@backstage/test-utils` needs to depend on `@backstage/core`, core is not able to use those test-utils. We put any test-utils that don't need to depend on other Backstage packages in this package, in order for them to be usable by any other `@backstage` packages.
+
+## Documentation
+
+- [Backstage Readme](https://github.com/spotify/backstage/blob/master/README.md)
+- [Backstage Documentation](https://github.com/spotify/backstage/blob/master/docs/README.md)
diff --git a/packages/test-utils-core/package.json b/packages/test-utils-core/package.json
new file mode 100644
index 0000000000..79d36a3525
--- /dev/null
+++ b/packages/test-utils-core/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "@backstage/test-utils-core",
+ "description": "Utilities to test Backstage core",
+ "version": "0.1.1-alpha.3",
+ "private": false,
+ "publishConfig": {
+ "access": "public"
+ },
+ "homepage": "https://backstage.io",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/spotify/backstage",
+ "directory": "packages/test-utils-core"
+ },
+ "keywords": [
+ "backstage"
+ ],
+ "license": "Apache-2.0",
+ "main": "dist/index.cjs.js",
+ "types": "dist/index.d.ts",
+ "scripts": {
+ "build": "backstage-cli plugin:build",
+ "lint": "backstage-cli lint",
+ "test": "backstage-cli test"
+ },
+ "dependencies": {
+ "@testing-library/jest-dom": "^4.2.4",
+ "@testing-library/react": "^9.3.2",
+ "@types/jest": "^24.0.0",
+ "@types/node": "^12.0.0",
+ "react": "^16.12.0",
+ "react-dom": "^16.12.0"
+ }
+}
diff --git a/packages/test-utils-core/src/index.ts b/packages/test-utils-core/src/index.ts
new file mode 100644
index 0000000000..43faf28a4a
--- /dev/null
+++ b/packages/test-utils-core/src/index.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 * from './testUtils';
diff --git a/packages/test-utils-core/src/setupTests.ts b/packages/test-utils-core/src/setupTests.ts
new file mode 100644
index 0000000000..8925258421
--- /dev/null
+++ b/packages/test-utils-core/src/setupTests.ts
@@ -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.
+ */
+
+import '@testing-library/jest-dom/extend-expect';
diff --git a/packages/test-utils/src/testUtils/Keyboard.js b/packages/test-utils-core/src/testUtils/Keyboard.js
similarity index 99%
rename from packages/test-utils/src/testUtils/Keyboard.js
rename to packages/test-utils-core/src/testUtils/Keyboard.js
index e3225f2342..8f4a48b0b4 100644
--- a/packages/test-utils/src/testUtils/Keyboard.js
+++ b/packages/test-utils-core/src/testUtils/Keyboard.js
@@ -23,7 +23,7 @@ const codes = {
Esc: 27,
};
-export default class Keyboard {
+export class Keyboard {
static async type(target, input) {
await new Keyboard(target).type(input);
}
diff --git a/packages/test-utils/src/testUtils/Keyboard.test.js b/packages/test-utils-core/src/testUtils/Keyboard.test.js
similarity index 98%
rename from packages/test-utils/src/testUtils/Keyboard.test.js
rename to packages/test-utils-core/src/testUtils/Keyboard.test.js
index 31e0885dc1..48b8522c0c 100644
--- a/packages/test-utils/src/testUtils/Keyboard.test.js
+++ b/packages/test-utils-core/src/testUtils/Keyboard.test.js
@@ -15,7 +15,7 @@
*/
import React from 'react';
-import Keyboard from './Keyboard';
+import { Keyboard } from './Keyboard';
import { render } from '@testing-library/react';
describe('testUtils.Keyboard', () => {
diff --git a/packages/test-utils-core/src/testUtils/index.tsx b/packages/test-utils-core/src/testUtils/index.tsx
new file mode 100644
index 0000000000..7558f32819
--- /dev/null
+++ b/packages/test-utils-core/src/testUtils/index.tsx
@@ -0,0 +1,19 @@
+/*
+ * 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 * from './Keyboard';
+export * from './logCollector';
+export * from './testingLibrary';
diff --git a/packages/test-utils/src/testUtils/logCollector.test.ts b/packages/test-utils-core/src/testUtils/logCollector.test.ts
similarity index 100%
rename from packages/test-utils/src/testUtils/logCollector.test.ts
rename to packages/test-utils-core/src/testUtils/logCollector.test.ts
diff --git a/packages/test-utils/src/testUtils/logCollector.ts b/packages/test-utils-core/src/testUtils/logCollector.ts
similarity index 100%
rename from packages/test-utils/src/testUtils/logCollector.ts
rename to packages/test-utils-core/src/testUtils/logCollector.ts
diff --git a/packages/test-utils/src/testUtils/testingLibrary.ts b/packages/test-utils-core/src/testUtils/testingLibrary.ts
similarity index 100%
rename from packages/test-utils/src/testUtils/testingLibrary.ts
rename to packages/test-utils-core/src/testUtils/testingLibrary.ts
diff --git a/packages/test-utils-core/tsconfig.json b/packages/test-utils-core/tsconfig.json
new file mode 100644
index 0000000000..7b73db2f0f
--- /dev/null
+++ b/packages/test-utils-core/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": ["src"],
+ "compilerOptions": {
+ "baseUrl": "src"
+ }
+}
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index 55b7436aae..ab52ca94a1 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -39,6 +39,7 @@
},
"peerDependencies": {
"@backstage/theme": "^0.1.1-alpha.3",
+ "@backstage/test-utils-core": "^0.1.1-alpha.3",
"@material-ui/core": "^4.9.1",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
diff --git a/packages/test-utils/src/index.ts b/packages/test-utils/src/index.ts
index 43faf28a4a..57b7fd6773 100644
--- a/packages/test-utils/src/index.ts
+++ b/packages/test-utils/src/index.ts
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export * from './testUtils';
+export * from '@backstage/test-utils-core';
diff --git a/packages/test-utils/src/testUtils/appWrappers.test.tsx b/packages/test-utils/src/testUtils/appWrappers.test.tsx
new file mode 100644
index 0000000000..e2f1b6b7cb
--- /dev/null
+++ b/packages/test-utils/src/testUtils/appWrappers.test.tsx
@@ -0,0 +1,35 @@
+/*
+ * 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 } from '@testing-library/react';
+import { wrapInTestApp } from './appWrappers';
+import { Route } from 'react-router';
+
+describe('wrapInTestApp', () => {
+ it('should provide routing', () => {
+ const rendered = render(
+ wrapInTestApp(
+ <>
+ Route 1
+ Route 2
+ >,
+ ['/route2'],
+ ),
+ );
+ expect(rendered.getByText('Route 2')).toBeInTheDocument();
+ });
+});
diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx
index 6aac9c5542..93f92ec537 100644
--- a/packages/test-utils/src/testUtils/appWrappers.tsx
+++ b/packages/test-utils/src/testUtils/appWrappers.tsx
@@ -20,10 +20,6 @@ import { MemoryRouter } from 'react-router';
import { Route } from 'react-router-dom';
import { BackstageTheme } from '@backstage/theme';
-export { default as Keyboard } from './Keyboard';
-export { default as mockBreakpoint } from './mockBreakpoint';
-export * from './logCollector';
-
export function wrapInTestApp(
Component: ComponentType | ReactNode,
initialRouterEntries: string[] = ['/'],
diff --git a/packages/test-utils/src/testUtils/index.tsx b/packages/test-utils/src/testUtils/index.tsx
index 3e8305e0fb..ea33de2f31 100644
--- a/packages/test-utils/src/testUtils/index.tsx
+++ b/packages/test-utils/src/testUtils/index.tsx
@@ -14,8 +14,5 @@
* limitations under the License.
*/
-export { default as Keyboard } from './Keyboard';
export { default as mockBreakpoint } from './mockBreakpoint';
export * from './appWrappers';
-export * from './logCollector';
-export * from './testingLibrary';
diff --git a/packages/theme/src/BackstageTheme.ts b/packages/theme/src/BackstageTheme.ts
index 202bdbc08c..4f61437400 100644
--- a/packages/theme/src/BackstageTheme.ts
+++ b/packages/theme/src/BackstageTheme.ts
@@ -20,10 +20,11 @@ import { blue, yellow } from '@material-ui/core/colors';
import { BackstageMuiTheme, BackstageMuiThemeOptions } from './types';
-export const COLORS = {
+const COLORS = {
PAGE_BACKGROUND: '#F8F8F8',
DEFAULT_PAGE_THEME_COLOR: '#7C3699',
DEFAULT_PAGE_THEME_LIGHT_COLOR: '#ECDBF2',
+ SIDEBAR_BACKGROUND_COLOR: '#171717',
ERROR_BACKGROUND_COLOR: '#FFEBEE',
ERROR_TEXT_COLOR: '#CA001B',
INFO_TEXT_COLOR: '#004e8a',
@@ -86,6 +87,7 @@ const extendedThemeConfig: BackstageMuiThemeOptions = {
linkHover: COLORS.LINK_TEXT_HOVER,
link: COLORS.LINK_TEXT,
gold: yellow.A700,
+ sidebar: COLORS.SIDEBAR_BACKGROUND_COLOR,
},
navigation: {
width: 220,
diff --git a/packages/theme/src/BackstageThemeDark.ts b/packages/theme/src/BackstageThemeDark.ts
index b8b89c8f0a..9952a5eeaa 100644
--- a/packages/theme/src/BackstageThemeDark.ts
+++ b/packages/theme/src/BackstageThemeDark.ts
@@ -20,11 +20,11 @@ import { blue, yellow } from '@material-ui/core/colors';
import { BackstageMuiTheme, BackstageMuiThemeOptions } from './types';
-export const COLORS = {
+const COLORS = {
PAGE_BACKGROUND: '#282828',
- EFAULT_PAGE_THEME_COLOR: '#232323',
DEFAULT_PAGE_THEME_COLOR: '#7C3699',
DEFAULT_PAGE_THEME_LIGHT_COLOR: '#ECDBF2',
+ SIDEBAR_BACKGROUND_COLOR: '#424242',
ERROR_BACKGROUND_COLOR: '#FFEBEE',
ERROR_TEXT_COLOR: '#CA001B',
INFO_TEXT_COLOR: '#004e8a',
@@ -91,6 +91,7 @@ const extendedThemeConfig: BackstageMuiThemeOptions = {
linkHover: COLORS.LINK_TEXT_HOVER,
link: COLORS.LINK_TEXT,
gold: yellow.A700,
+ sidebar: COLORS.SIDEBAR_BACKGROUND_COLOR,
},
navigation: {
width: 220,
diff --git a/packages/theme/src/BackstageThemeLight.ts b/packages/theme/src/BackstageThemeLight.ts
index 14bc942910..a0a063ad24 100644
--- a/packages/theme/src/BackstageThemeLight.ts
+++ b/packages/theme/src/BackstageThemeLight.ts
@@ -20,10 +20,11 @@ import { blue, yellow } from '@material-ui/core/colors';
import { BackstageMuiTheme, BackstageMuiThemeOptions } from './types';
-export const COLORS = {
+const COLORS = {
PAGE_BACKGROUND: '#F8F8F8',
DEFAULT_PAGE_THEME_COLOR: '#7C3699',
DEFAULT_PAGE_THEME_LIGHT_COLOR: '#ECDBF2',
+ SIDEBAR_BACKGROUND_COLOR: '#171717',
ERROR_BACKGROUND_COLOR: '#FFEBEE',
ERROR_TEXT_COLOR: '#CA001B',
INFO_TEXT_COLOR: '#004e8a',
@@ -89,6 +90,7 @@ const extendedThemeConfig: BackstageMuiThemeOptions = {
linkHover: COLORS.LINK_TEXT_HOVER,
link: COLORS.LINK_TEXT,
gold: yellow.A700,
+ sidebar: COLORS.SIDEBAR_BACKGROUND_COLOR,
},
navigation: {
width: 220,
diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts
index 136355dc37..8aa7e30ef5 100644
--- a/packages/theme/src/index.ts
+++ b/packages/theme/src/index.ts
@@ -15,4 +15,4 @@
*/
export { default as BackstageThemeLight } from './BackstageThemeLight';
export { default as BackstageThemeDark } from './BackstageThemeDark';
-export { default as BackstageTheme, COLORS } from './BackstageTheme';
+export { default as BackstageTheme } from './BackstageTheme';
diff --git a/packages/theme/src/types.ts b/packages/theme/src/types.ts
index 9a3e93c3a9..cbd3de4efa 100644
--- a/packages/theme/src/types.ts
+++ b/packages/theme/src/types.ts
@@ -38,6 +38,7 @@ export type BackstageMuiPalette = Theme['palette'] & {
linkHover: string;
link: string;
gold: string;
+ sidebar: string;
bursts: {
fontColor: string;
slackChannelText: string;
diff --git a/plugins/lighthouse/src/components/CategoryTrendline/index.tsx b/plugins/lighthouse/src/components/CategoryTrendline/index.tsx
index 95622ed918..a46aff52e5 100644
--- a/plugins/lighthouse/src/components/CategoryTrendline/index.tsx
+++ b/plugins/lighthouse/src/components/CategoryTrendline/index.tsx
@@ -15,22 +15,28 @@
*/
import React, { FC } from 'react';
import { Sparklines, SparklinesLine, SparklinesProps } from 'react-sparklines';
-import { COLORS } from '@backstage/theme';
+import { useTheme } from '@material-ui/core';
+import { BackstageTheme } from '@backstage/theme';
-function color(data: number[]): string | undefined {
+function color(
+ data: number[],
+ theme: typeof BackstageTheme,
+): string | undefined {
const lastNum = data[data.length - 1];
if (!lastNum) return undefined;
- if (lastNum >= 0.9) return COLORS.STATUS.OK;
- if (lastNum >= 0.5) return COLORS.STATUS.WARNING;
- return COLORS.STATUS.ERROR;
+ if (lastNum >= 0.9) return theme.palette.status.ok;
+ if (lastNum >= 0.5) return theme.palette.status.warning;
+ return theme.palette.status.error;
}
const CategoryTrendline: FC = props => {
+ const theme = useTheme();
+
if (!props.data) return null;
return (
{props.title && {props.title}}
-
+
);
};
diff --git a/yarn.lock b/yarn.lock
index 03f14af1bf..22ba268f8d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2901,6 +2901,25 @@
qs "^6.6.0"
ts-dedent "^1.1.0"
+"@storybook/addon-storysource@^5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-5.3.18.tgz#003374d76c0898c3b74aa4cd008f444eb6b63c68"
+ integrity sha512-uMSu505rbcNErAYngV5raVRQ/eMiOtGNA88WxNzD/8h/0EVpEXlBAewiGzAmooNhCa/3O3iPuwka8Cky6aWPOA==
+ dependencies:
+ "@storybook/addons" "5.3.18"
+ "@storybook/components" "5.3.18"
+ "@storybook/router" "5.3.18"
+ "@storybook/source-loader" "5.3.18"
+ "@storybook/theming" "5.3.18"
+ core-js "^3.0.1"
+ estraverse "^4.2.0"
+ loader-utils "^1.2.3"
+ prettier "^1.16.4"
+ prop-types "^15.7.2"
+ react-syntax-highlighter "^11.0.2"
+ regenerator-runtime "^0.13.3"
+ util-deprecate "^1.0.2"
+
"@storybook/addons@5.3.17", "@storybook/addons@^5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/addons/-/addons-5.3.17.tgz#8efab65904040b0b8578eedc9a5772dbcbf6fa83"
@@ -2914,6 +2933,19 @@
global "^4.3.2"
util-deprecate "^1.0.2"
+"@storybook/addons@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/addons/-/addons-5.3.18.tgz#5cbba6407ef7a802041c5ee831473bc3bed61f64"
+ integrity sha512-ZQjDgTUDFRLvAiBg2d8FgPgghfQ+9uFyXQbtiGlTBLinrPCeQd7J86qiUES0fcGoohCCw0wWKtvB0WF2z1XNDg==
+ dependencies:
+ "@storybook/api" "5.3.18"
+ "@storybook/channels" "5.3.18"
+ "@storybook/client-logger" "5.3.18"
+ "@storybook/core-events" "5.3.18"
+ core-js "^3.0.1"
+ global "^4.3.2"
+ util-deprecate "^1.0.2"
+
"@storybook/api@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/api/-/api-5.3.17.tgz#1c0dad3309afef6b0a5585cb59c65824fb4d2721"
@@ -2940,6 +2972,32 @@
telejson "^3.2.0"
util-deprecate "^1.0.2"
+"@storybook/api@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/api/-/api-5.3.18.tgz#95582ab90d947065e0e34ed603650a3630dcbd16"
+ integrity sha512-QXaccNCARHzPWOuxYndiebGWBZmwiUvRgB9ji0XTJBS3y8K0ZPb5QyuqiKPaEWUj8dBA8rzdDtkW3Yt95Namaw==
+ dependencies:
+ "@reach/router" "^1.2.1"
+ "@storybook/channels" "5.3.18"
+ "@storybook/client-logger" "5.3.18"
+ "@storybook/core-events" "5.3.18"
+ "@storybook/csf" "0.0.1"
+ "@storybook/router" "5.3.18"
+ "@storybook/theming" "5.3.18"
+ "@types/reach__router" "^1.2.3"
+ core-js "^3.0.1"
+ fast-deep-equal "^2.0.1"
+ global "^4.3.2"
+ lodash "^4.17.15"
+ memoizerific "^1.11.3"
+ prop-types "^15.6.2"
+ react "^16.8.3"
+ semver "^6.0.0"
+ shallow-equal "^1.1.0"
+ store2 "^2.7.1"
+ telejson "^3.2.0"
+ util-deprecate "^1.0.2"
+
"@storybook/channel-postmessage@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-5.3.17.tgz#807b6316cd0e52d9f27363d5092ad1cd896b694c"
@@ -2958,6 +3016,13 @@
dependencies:
core-js "^3.0.1"
+"@storybook/channels@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/channels/-/channels-5.3.18.tgz#490c9eaa8292b0571c0f665052b12addf7c35f21"
+ integrity sha512-scP/6td/BJSEOgfN+qaYGDf3E793xye7tIw6W+sYqwg+xdMFO39wVXgVZNpQL6sLEwpJZTaPywCjC6p6ksErqQ==
+ dependencies:
+ core-js "^3.0.1"
+
"@storybook/client-api@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/client-api/-/client-api-5.3.17.tgz#fc1d247caf267ebcc6ddf957fca7e02ae752d99e"
@@ -2988,6 +3053,13 @@
dependencies:
core-js "^3.0.1"
+"@storybook/client-logger@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-5.3.18.tgz#27c9d09d788965db0164be6e168bc3f03adbf88f"
+ integrity sha512-RZjxw4uqZX3Yk27IirbB/pQG+wRsQSSRlKqYa8KQ5bSanm4IrcV9VA1OQbuySW9njE+CexAnakQJ/fENdmurNg==
+ dependencies:
+ core-js "^3.0.1"
+
"@storybook/components@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/components/-/components-5.3.17.tgz#287430fc9c5f59b1d3590b50b3c7688355b22639"
@@ -3015,6 +3087,33 @@
simplebar-react "^1.0.0-alpha.6"
ts-dedent "^1.1.0"
+"@storybook/components@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/components/-/components-5.3.18.tgz#528f6ab1660981e948993a04b407a6fad7751589"
+ integrity sha512-LIN4aVCCDY7klOwtuqQhfYz4tHaMADhXEzZpij+3r8N68Inck6IJ1oo9A9umXQPsTioQi8e6FLobH1im90j/2A==
+ dependencies:
+ "@storybook/client-logger" "5.3.18"
+ "@storybook/theming" "5.3.18"
+ "@types/react-syntax-highlighter" "11.0.4"
+ "@types/react-textarea-autosize" "^4.3.3"
+ core-js "^3.0.1"
+ global "^4.3.2"
+ lodash "^4.17.15"
+ markdown-to-jsx "^6.9.1"
+ memoizerific "^1.11.3"
+ polished "^3.3.1"
+ popper.js "^1.14.7"
+ prop-types "^15.7.2"
+ react "^16.8.3"
+ react-dom "^16.8.3"
+ react-focus-lock "^2.1.0"
+ react-helmet-async "^1.0.2"
+ react-popper-tooltip "^2.8.3"
+ react-syntax-highlighter "^11.0.2"
+ react-textarea-autosize "^7.1.0"
+ simplebar-react "^1.0.0-alpha.6"
+ ts-dedent "^1.1.0"
+
"@storybook/core-events@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.3.17.tgz#698ce0a36c29fe8fa04608f56ccca53aa1d31638"
@@ -3022,6 +3121,13 @@
dependencies:
core-js "^3.0.1"
+"@storybook/core-events@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/core-events/-/core-events-5.3.18.tgz#e5d335f8a2c7dd46502b8f505006f1e111b46d49"
+ integrity sha512-uQ6NYJ5WODXK8DJ7m8y3yUAtWB3n+6XtYztjY+tdkCsLYvTYDXNS+epV+f5Hu9+gB+/Dm+b5Su4jDD+LZB2QWA==
+ dependencies:
+ core-js "^3.0.1"
+
"@storybook/core@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/core/-/core-5.3.17.tgz#abd09dc416f87c7954ef3615bc3f4898c93e2b45"
@@ -3162,6 +3268,37 @@
qs "^6.6.0"
util-deprecate "^1.0.2"
+"@storybook/router@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/router/-/router-5.3.18.tgz#8ab22f1f2f7f957e78baf992030707a62289076e"
+ integrity sha512-6B2U2C75KTSVaCuYYgcubeJGcCSnwsXuEf50hEd5mGqWgHZfojCtGvB7Ko4X+0h8rEC+eNA4p7YBOhlUv9WNrQ==
+ dependencies:
+ "@reach/router" "^1.2.1"
+ "@storybook/csf" "0.0.1"
+ "@types/reach__router" "^1.2.3"
+ core-js "^3.0.1"
+ global "^4.3.2"
+ lodash "^4.17.15"
+ memoizerific "^1.11.3"
+ qs "^6.6.0"
+ util-deprecate "^1.0.2"
+
+"@storybook/source-loader@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-5.3.18.tgz#39ba28d9664ab8204d6b04ee757772369931e7e5"
+ integrity sha512-oljmLt3KMu17W9FAaEgocsI6wrloWczS26SVXadzbDbL+8Tu6vTeFJSd6HcY+e4JIIKjuze0kmaVhpi6wwPbZQ==
+ dependencies:
+ "@storybook/addons" "5.3.18"
+ "@storybook/client-logger" "5.3.18"
+ "@storybook/csf" "0.0.1"
+ core-js "^3.0.1"
+ estraverse "^4.2.0"
+ global "^4.3.2"
+ loader-utils "^1.2.3"
+ prettier "^1.16.4"
+ prop-types "^15.7.2"
+ regenerator-runtime "^0.13.3"
+
"@storybook/theming@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/theming/-/theming-5.3.17.tgz#cf6278c4857229c7167faf04d5b2206bc5ee04e1"
@@ -3180,6 +3317,24 @@
resolve-from "^5.0.0"
ts-dedent "^1.1.0"
+"@storybook/theming@5.3.18":
+ version "5.3.18"
+ resolved "https://registry.npmjs.org/@storybook/theming/-/theming-5.3.18.tgz#35e78de79d9cf8f1248af0dd1c7fa60555761312"
+ integrity sha512-lfFTeLoYwLMKg96N3gn0umghMdAHgJBGuk2OM8Ll84yWtdl9RGnzfiI1Fl7Cr5k95dCF7drLJlJCao1VxUkFSA==
+ dependencies:
+ "@emotion/core" "^10.0.20"
+ "@emotion/styled" "^10.0.17"
+ "@storybook/client-logger" "5.3.18"
+ core-js "^3.0.1"
+ deep-object-diff "^1.1.0"
+ emotion-theming "^10.0.19"
+ global "^4.3.2"
+ memoizerific "^1.11.3"
+ polished "^3.3.1"
+ prop-types "^15.7.2"
+ resolve-from "^5.0.0"
+ ts-dedent "^1.1.0"
+
"@storybook/ui@5.3.17":
version "5.3.17"
resolved "https://registry.npmjs.org/@storybook/ui/-/ui-5.3.17.tgz#2d47617896a2d928fb79dc8a0e709cee9b57cc50"
@@ -15765,7 +15920,7 @@ prepend-http@^1.0.0, prepend-http@^1.0.1:
resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
-prettier@^1.18.2, prettier@^1.19.1:
+prettier@^1.16.4, prettier@^1.18.2, prettier@^1.19.1:
version "1.19.1"
resolved "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==