Merge pull request #24880 from debsmita1/status-icons
adds icons to status component
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Adds icons to status component
|
||||
@@ -28,42 +28,58 @@ import {
|
||||
|
||||
describe('<StatusOK />', () => {
|
||||
it('renders without exploding', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(<StatusOK />);
|
||||
const { getByLabelText, getByTestId } = await renderInTestApp(<StatusOK />);
|
||||
expect(getByLabelText('Status ok')).toBeInTheDocument();
|
||||
expect(getByTestId('status-ok')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('<StatusWarning />', () => {
|
||||
it('renders without exploding', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(<StatusWarning />);
|
||||
const { getByLabelText, getByTestId } = await renderInTestApp(
|
||||
<StatusWarning />,
|
||||
);
|
||||
expect(getByLabelText('Status warning')).toBeInTheDocument();
|
||||
expect(getByTestId('status-warning')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('<StatusError />', () => {
|
||||
it('renders without exploding', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(<StatusError />);
|
||||
const { getByLabelText, getByTestId } = await renderInTestApp(
|
||||
<StatusError />,
|
||||
);
|
||||
expect(getByLabelText('Status error')).toBeInTheDocument();
|
||||
expect(getByTestId('status-error')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('<StatusPending />', () => {
|
||||
it('renders without exploding', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(<StatusPending />);
|
||||
const { getByLabelText, getByTestId } = await renderInTestApp(
|
||||
<StatusPending />,
|
||||
);
|
||||
expect(getByLabelText('Status pending')).toBeInTheDocument();
|
||||
expect(getByTestId('status-pending')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('<StatusRunning />', () => {
|
||||
it('renders without exploding', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(<StatusRunning />);
|
||||
const { getByLabelText, getByTestId } = await renderInTestApp(
|
||||
<StatusRunning />,
|
||||
);
|
||||
expect(getByLabelText('Status running')).toBeInTheDocument();
|
||||
expect(getByTestId('status-running')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('<StatusAborted />', () => {
|
||||
it('renders without exploding', async () => {
|
||||
const { getByLabelText } = await renderInTestApp(<StatusAborted />);
|
||||
const { getByLabelText, getByTestId } = await renderInTestApp(
|
||||
<StatusAborted />,
|
||||
);
|
||||
expect(getByLabelText('Status aborted')).toBeInTheDocument();
|
||||
expect(getByTestId('status-aborted')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline';
|
||||
import WarningOutline from '@material-ui/icons/ReportProblemOutlined';
|
||||
import ErrorOutline from '@material-ui/icons/ErrorOutline';
|
||||
import classNames from 'classnames';
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import { PendingIcon } from './icons/PendingIcon';
|
||||
import { RunningIcon } from './icons/RunningIcon';
|
||||
import { AbortedIcon } from './icons/AbortedIcon';
|
||||
|
||||
export type StatusClassKey =
|
||||
| 'status'
|
||||
@@ -32,123 +38,185 @@ const useStyles = makeStyles(
|
||||
theme => ({
|
||||
status: {
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
'&::before': {
|
||||
width: '0.7em',
|
||||
height: '0.7em',
|
||||
display: 'inline-block',
|
||||
marginRight: theme.spacing(1),
|
||||
borderRadius: '50%',
|
||||
content: '""',
|
||||
},
|
||||
alignItems: 'baseline',
|
||||
display: 'flex',
|
||||
},
|
||||
statusIcon: {
|
||||
flexShrink: 0,
|
||||
position: 'relative',
|
||||
top: '0.125em',
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
statusIconSize: {
|
||||
width: '0.8em',
|
||||
height: '0.8em',
|
||||
},
|
||||
statusIconSizeForImg: {
|
||||
width: '1.2em',
|
||||
height: '1.2em',
|
||||
},
|
||||
ok: {
|
||||
'&::before': {
|
||||
backgroundColor: theme.palette.status.ok,
|
||||
},
|
||||
fill: theme.palette.status.ok || '#3E8635',
|
||||
},
|
||||
warning: {
|
||||
'&::before': {
|
||||
backgroundColor: theme.palette.status.warning,
|
||||
},
|
||||
fill: theme.palette.status.warning || '#F0AB00',
|
||||
},
|
||||
error: {
|
||||
'&::before': {
|
||||
backgroundColor: theme.palette.status.error,
|
||||
},
|
||||
fill: theme.palette.status.error || '#C9190B',
|
||||
},
|
||||
pending: {
|
||||
'&::before': {
|
||||
backgroundColor: theme.palette.status.pending,
|
||||
},
|
||||
fill: theme.palette.status.aborted || '#6A6E73',
|
||||
},
|
||||
running: {
|
||||
'&::before': {
|
||||
backgroundColor: theme.palette.status.running,
|
||||
},
|
||||
fill: theme.palette.status.aborted || '#6A6E73',
|
||||
},
|
||||
aborted: {
|
||||
'&::before': {
|
||||
backgroundColor: theme.palette.status.aborted,
|
||||
},
|
||||
fill: theme.palette.status.aborted || '#6A6E73',
|
||||
},
|
||||
}),
|
||||
{ name: 'BackstageStatus' },
|
||||
);
|
||||
|
||||
export function StatusOK(props: PropsWithChildren<{}>) {
|
||||
const classes = useStyles(props);
|
||||
const { children, ...otherProps } = props;
|
||||
const classes = useStyles(otherProps);
|
||||
return (
|
||||
<Typography
|
||||
component="span"
|
||||
className={classNames(classes.status, classes.ok)}
|
||||
className={classNames(classes.status)}
|
||||
aria-label="Status ok"
|
||||
aria-hidden="true"
|
||||
{...props}
|
||||
/>
|
||||
{...otherProps}
|
||||
>
|
||||
<CheckCircleOutline
|
||||
data-testid="status-ok"
|
||||
className={classNames(
|
||||
classes.ok,
|
||||
classes.statusIconSize,
|
||||
classes.statusIcon,
|
||||
)}
|
||||
/>
|
||||
{children}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function StatusWarning(props: PropsWithChildren<{}>) {
|
||||
const classes = useStyles(props);
|
||||
const { children, ...otherProps } = props;
|
||||
const classes = useStyles(otherProps);
|
||||
return (
|
||||
<Typography
|
||||
component="span"
|
||||
className={classNames(classes.status, classes.warning)}
|
||||
className={classNames(classes.status)}
|
||||
aria-label="Status warning"
|
||||
aria-hidden="true"
|
||||
{...props}
|
||||
/>
|
||||
{...otherProps}
|
||||
>
|
||||
<WarningOutline
|
||||
data-testid="status-warning"
|
||||
className={classNames(
|
||||
classes.warning,
|
||||
classes.statusIconSize,
|
||||
classes.statusIcon,
|
||||
)}
|
||||
/>
|
||||
{children}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function StatusError(props: PropsWithChildren<{}>) {
|
||||
const classes = useStyles(props);
|
||||
const { children, ...otherProps } = props;
|
||||
const classes = useStyles(otherProps);
|
||||
return (
|
||||
<Typography
|
||||
component="span"
|
||||
className={classNames(classes.status, classes.error)}
|
||||
className={classNames(classes.status)}
|
||||
aria-label="Status error"
|
||||
aria-hidden="true"
|
||||
{...props}
|
||||
/>
|
||||
{...otherProps}
|
||||
>
|
||||
<ErrorOutline
|
||||
data-testid="status-error"
|
||||
className={classNames(
|
||||
classes.error,
|
||||
classes.statusIconSize,
|
||||
classes.statusIcon,
|
||||
)}
|
||||
/>
|
||||
{children}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function StatusPending(props: PropsWithChildren<{}>) {
|
||||
const classes = useStyles(props);
|
||||
const { children, ...otherProps } = props;
|
||||
const classes = useStyles(otherProps);
|
||||
return (
|
||||
<Typography
|
||||
component="span"
|
||||
className={classNames(classes.status, classes.pending)}
|
||||
className={classNames(classes.status)}
|
||||
aria-label="Status pending"
|
||||
aria-hidden="true"
|
||||
{...props}
|
||||
/>
|
||||
{...otherProps}
|
||||
>
|
||||
<PendingIcon
|
||||
dataTestId="status-pending"
|
||||
className={classNames(
|
||||
classes.pending,
|
||||
classes.statusIconSizeForImg,
|
||||
classes.statusIcon,
|
||||
)}
|
||||
/>
|
||||
{children}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function StatusRunning(props: PropsWithChildren<{}>) {
|
||||
const classes = useStyles(props);
|
||||
const { children, ...otherProps } = props;
|
||||
const classes = useStyles(otherProps);
|
||||
return (
|
||||
<Typography
|
||||
component="span"
|
||||
className={classNames(classes.status, classes.running)}
|
||||
className={classNames(classes.status)}
|
||||
aria-label="Status running"
|
||||
aria-hidden="true"
|
||||
{...props}
|
||||
/>
|
||||
{...otherProps}
|
||||
>
|
||||
<RunningIcon
|
||||
dataTestId="status-running"
|
||||
className={classNames(
|
||||
classes.running,
|
||||
classes.statusIcon,
|
||||
classes.statusIconSizeForImg,
|
||||
)}
|
||||
/>
|
||||
{children}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
export function StatusAborted(props: PropsWithChildren<{}>) {
|
||||
const classes = useStyles(props);
|
||||
const { children, ...otherProps } = props;
|
||||
const classes = useStyles(otherProps);
|
||||
return (
|
||||
<Typography
|
||||
component="span"
|
||||
className={classNames(classes.status, classes.aborted)}
|
||||
className={classNames(classes.status)}
|
||||
aria-label="Status aborted"
|
||||
aria-hidden="true"
|
||||
{...props}
|
||||
/>
|
||||
{...otherProps}
|
||||
>
|
||||
<AbortedIcon
|
||||
dataTestId="status-aborted"
|
||||
className={classNames(
|
||||
classes.aborted,
|
||||
classes.statusIcon,
|
||||
classes.statusIconSizeForImg,
|
||||
)}
|
||||
/>
|
||||
{children}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* 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 * as React from 'react';
|
||||
|
||||
export const AbortedIcon = ({
|
||||
className,
|
||||
dataTestId,
|
||||
}: {
|
||||
className: string;
|
||||
dataTestId: string;
|
||||
}): React.ReactElement => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 -960 960 960"
|
||||
className={className}
|
||||
data-testid={dataTestId}
|
||||
>
|
||||
<path d="M140-440q-25 0-42.5-17.5T80-500q0-25 17.5-42.5T140-560h240q25 0 42.5 17.5T440-500q0 25-17.5 42.5T380-440H140Zm440 0q-25 0-42.5-17.5T520-500q0-25 17.5-42.5T580-560h240q25 0 42.5 17.5T880-500q0 25-17.5 42.5T820-440H580Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* 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 * as React from 'react';
|
||||
|
||||
export const PendingIcon = ({
|
||||
className,
|
||||
dataTestId,
|
||||
}: {
|
||||
className: string;
|
||||
dataTestId: string;
|
||||
}): React.ReactElement => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 -960 960 960"
|
||||
className={className}
|
||||
data-testid={dataTestId}
|
||||
>
|
||||
<path d="M280-420q25 0 42.5-17.5T340-480q0-25-17.5-42.5T280-540q-25 0-42.5 17.5T220-480q0 25 17.5 42.5T280-420Zm200 0q25 0 42.5-17.5T540-480q0-25-17.5-42.5T480-540q-25 0-42.5 17.5T420-480q0 25 17.5 42.5T480-420Zm200 0q25 0 42.5-17.5T740-480q0-25-17.5-42.5T680-540q-25 0-42.5 17.5T620-480q0 25 17.5 42.5T680-420ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* 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 * as React from 'react';
|
||||
|
||||
export const RunningIcon = ({
|
||||
className,
|
||||
dataTestId,
|
||||
}: {
|
||||
className: string;
|
||||
dataTestId: string;
|
||||
}): React.ReactElement => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 -960 960 960"
|
||||
className={className}
|
||||
data-testid={dataTestId}
|
||||
>
|
||||
<path d="M480-80q-82 0-155-31.5t-127.5-86Q143-252 111.5-325T80-480q0-83 31.5-155.5t86-127Q252-817 325-848.5T480-880q17 0 28.5 11.5T520-840q0 17-11.5 28.5T480-800q-133 0-226.5 93.5T160-480q0 133 93.5 226.5T480-160q133 0 226.5-93.5T800-480q0-17 11.5-28.5T840-520q17 0 28.5 11.5T880-480q0 82-31.5 155t-86 127.5q-54.5 54.5-127 86T480-80Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user