diff --git a/packages/core/src/components/CircleProgress.js b/packages/core/src/components/CircleProgress.js
deleted file mode 100644
index f11f9d193b..0000000000
--- a/packages/core/src/components/CircleProgress.js
+++ /dev/null
@@ -1,105 +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 { withStyles } from '@material-ui/core';
-import { Circle } from 'rc-progress';
-import { COLORS, V1 } from '../theme/BackstageTheme';
-
-const styles = theme => ({
- root: {
- position: 'relative',
- lineHeight: 0,
- },
- overlay: {
- position: 'absolute',
- top: '50%',
- left: '50%',
- transform: 'translate(-50%, -60%)',
- fontSize: 45,
- fontWeight: 'bold',
- color: theme.palette.textSubtle,
- },
- circle: {
- width: '80%',
- transform: 'translate(10%, 0)',
- },
-});
-
-class CircleProgress extends Component {
- static propTypes = {
- value: PropTypes.any.isRequired,
- fractional: PropTypes.bool,
- classes: PropTypes.object.isRequired,
- inverse: PropTypes.bool,
- unit: PropTypes.string,
- max: PropTypes.number,
- };
-
- static defaultProps = {
- fractional: true,
- inverse: false,
- unit: '%',
- max: 100,
- };
-
- static getProgressColor(value, inverse, max /* , classes */) {
- if (isNaN(value)) {
- return V1.palette.textVerySubtle;
- }
-
- const actualMax = max ? max : CircleProgress.defaultProps.max;
- const actualValue = inverse ? actualMax - value : value;
-
- if (actualValue < actualMax / 3) {
- return COLORS.STATUS.ERROR;
- } else if (actualValue < actualMax * (2 / 3)) {
- return COLORS.STATUS.WARNING;
- }
- return COLORS.STATUS.OK;
- }
-
- render() {
- const { value, fractional, classes, inverse, unit, max } = this.props;
-
- const asPercentage = fractional ? Math.round(value * max) : value;
- const asActual = max !== 100 ? Math.round(value) : asPercentage;
-
- return (
-
-
-
- {isNaN(value) ? 'N/A' : `${asActual}${unit}`}
-
-
- );
- }
-}
-
-export default withStyles(styles)(CircleProgress);
diff --git a/packages/core/src/components/CircleProgress.test.js b/packages/core/src/components/CircleProgress.test.js
index 9686a62c1c..7d4b294dc1 100644
--- a/packages/core/src/components/CircleProgress.test.js
+++ b/packages/core/src/components/CircleProgress.test.js
@@ -17,8 +17,8 @@
import React from 'react';
import { render } from '@testing-library/react';
import { wrapInThemedTestApp } from '../testUtils';
-import CircleProgress from './CircleProgress';
-import { COLORS, V1 } from '../theme/BackstageTheme';
+import CircleProgress, { getProgressColor } from './CircleProgress';
+import { COLORS } from '../theme/BackstageTheme';
describe('', () => {
it('renders without exploding', () => {
@@ -53,18 +53,16 @@ describe('', () => {
});
it('colors the progress correctly', () => {
- expect(CircleProgress.getProgressColor()).toBe(V1.palette.textVerySubtle);
- expect(CircleProgress.getProgressColor(10)).toBe(COLORS.STATUS.ERROR);
- expect(CircleProgress.getProgressColor(50)).toBe(COLORS.STATUS.WARNING);
- expect(CircleProgress.getProgressColor(90)).toBe(COLORS.STATUS.OK);
+ expect(getProgressColor()).toBe('#ddd');
+ expect(getProgressColor(10)).toBe(COLORS.STATUS.ERROR);
+ expect(getProgressColor(50)).toBe(COLORS.STATUS.WARNING);
+ expect(getProgressColor(90)).toBe(COLORS.STATUS.OK);
});
it('colors the inverse progress correctly', () => {
- expect(CircleProgress.getProgressColor()).toBe(V1.palette.textVerySubtle);
- expect(CircleProgress.getProgressColor(10, true)).toBe(COLORS.STATUS.OK);
- expect(CircleProgress.getProgressColor(50, true)).toBe(
- COLORS.STATUS.WARNING,
- );
- expect(CircleProgress.getProgressColor(90, true)).toBe(COLORS.STATUS.ERROR);
+ expect(getProgressColor()).toBe('#ddd');
+ expect(getProgressColor(10, true)).toBe(COLORS.STATUS.OK);
+ expect(getProgressColor(50, true)).toBe(COLORS.STATUS.WARNING);
+ expect(getProgressColor(90, true)).toBe(COLORS.STATUS.ERROR);
});
});
diff --git a/packages/core/src/components/CircleProgress.tsx b/packages/core/src/components/CircleProgress.tsx
new file mode 100644
index 0000000000..6d30916c81
--- /dev/null
+++ b/packages/core/src/components/CircleProgress.tsx
@@ -0,0 +1,103 @@
+/*
+ * 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 { makeStyles } from '@material-ui/core';
+import { Circle } from 'rc-progress';
+import React, { FC } from 'react';
+import { COLORS } from '../theme/BackstageTheme';
+import { BackstageTheme } from '../theme/theme';
+
+const useStyles = makeStyles((theme: BackstageTheme) => ({
+ root: {
+ position: 'relative',
+ lineHeight: 0,
+ },
+ overlay: {
+ position: 'absolute',
+ top: '50%',
+ left: '50%',
+ transform: 'translate(-50%, -60%)',
+ fontSize: 45,
+ fontWeight: 'bold',
+ color: theme.palette.textSubtle,
+ },
+ circle: {
+ width: '80%',
+ transform: 'translate(10%, 0)',
+ },
+ colorUnknown: {},
+}));
+
+type Props = {
+ value: number;
+ fractional?: boolean;
+ inverse?: boolean;
+ unit?: string;
+ max?: number;
+};
+
+const defaultProps = {
+ fractional: true,
+ inverse: false,
+ unit: '%',
+ max: 100,
+};
+
+export function getProgressColor(value, inverse, max) {
+ if (isNaN(value)) {
+ return '#ddd';
+ }
+
+ const actualMax = max ? max : defaultProps.max;
+ const actualValue = inverse ? actualMax - value : value;
+
+ if (actualValue < actualMax / 3) {
+ return COLORS.STATUS.ERROR;
+ } else if (actualValue < actualMax * (2 / 3)) {
+ return COLORS.STATUS.WARNING;
+ }
+
+ return COLORS.STATUS.OK;
+}
+
+const CircleProgress: FC = props => {
+ const classes = useStyles(props);
+ const { value, fractional, inverse, unit, max } = {
+ ...defaultProps,
+ ...props,
+ };
+
+ const asPercentage = fractional ? Math.round(value * max) : value;
+ const asActual = max !== 100 ? Math.round(value) : asPercentage;
+
+ return (
+
+
+
+ {isNaN(value) ? 'N/A' : `${asActual}${unit}`}
+
+
+ );
+};
+
+export default CircleProgress;
diff --git a/packages/core/src/components/ProgressCard.js b/packages/core/src/components/ProgressCard.js
deleted file mode 100644
index d83019bcf0..0000000000
--- a/packages/core/src/components/ProgressCard.js
+++ /dev/null
@@ -1,77 +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 { withStyles } from '@material-ui/core';
-
-import InfoCard from '../layout/InfoCard';
-import CircleProgress from './CircleProgress';
-
-const styles = {
- root: {
- height: '100%',
- width: 250,
- },
-};
-
-class ProgressCard extends Component {
- static propTypes = {
- classes: PropTypes.object.isRequired,
- title: PropTypes.string.isRequired,
- subheader: PropTypes.string,
- progress: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
- .isRequired,
- deepLink: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.shape({
- title: PropTypes.string.isRequired,
- link: PropTypes.string.isRequired,
- }),
- ]),
- gacontext: PropTypes.string,
- };
-
- render() {
- const {
- title,
- subheader,
- progress,
- deepLink,
- classes,
- variant,
- } = this.props;
- const link =
- deepLink &&
- (typeof deepLink === 'string'
- ? { title: 'View more', link: deepLink }
- : deepLink);
- return (
-
-
-
-
-
- );
- }
-}
-
-export default withStyles(styles)(ProgressCard);
diff --git a/packages/core/src/components/ProgressCard.tsx b/packages/core/src/components/ProgressCard.tsx
new file mode 100644
index 0000000000..6a3b87ba89
--- /dev/null
+++ b/packages/core/src/components/ProgressCard.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, { FC } from 'react';
+import { makeStyles } from '@material-ui/core';
+
+import InfoCard from '../layout/InfoCard';
+import CircleProgress from './CircleProgress';
+
+type Props = {
+ title: string;
+ subheader?: string;
+ variant?: string;
+ progress: number | string;
+ deepLink?: string | { title: string; link: string };
+ gacontext?: string;
+};
+
+const useStyles = makeStyles({
+ root: {
+ height: '100%',
+ width: 250,
+ },
+});
+
+const ProgressCard: FC = props => {
+ const classes = useStyles(props);
+ const { title, subheader, progress, deepLink, variant } = props;
+
+ // TODO(freben): Make type more strict when InfoCard is written in TS
+ let link: any = undefined;
+ if (deepLink) {
+ if (typeof deepLink === 'string') {
+ link = { title: 'View more', link: deepLink };
+ } else {
+ link = deepLink;
+ }
+ }
+
+ return (
+
+
+
+
+
+ );
+};
+
+export default ProgressCard;
diff --git a/packages/core/src/theme/theme.d.ts b/packages/core/src/theme/theme.d.ts
index 1e3a57dee3..db4dfe5e86 100644
--- a/packages/core/src/theme/theme.d.ts
+++ b/packages/core/src/theme/theme.d.ts
@@ -26,5 +26,18 @@ export type BackstageTheme = Theme & {
running: string;
background: string;
};
+ border: string;
+ textVerySubtle: string;
+ textSubtle: string;
+ highlight: string;
+ errorBackground: string;
+ warningBackground: string;
+ infoBackground: string;
+ errorText: string;
+ infoText: string;
+ warningText: string;
+ linkHover: string;
+ link: string;
+ gold: string;
};
};