From dfa9c1efb7b698de010172423f1a0c3936acbe60 Mon Sep 17 00:00:00 2001 From: Vio Date: Sun, 21 Nov 2021 23:13:52 +0100 Subject: [PATCH] feat(ui): SummaryItem - budgets --- .../summary-item.stories.storyshot | 34 ++++++ .../components/summary-item/summary-item.jsx | 59 +++++++++- .../summary-item/summary-item.module.css | 33 ++++++ .../summary-item/summary-item.stories.jsx | 110 ++++++++++-------- 4 files changed, 188 insertions(+), 48 deletions(-) diff --git a/packages/ui/build/storybook/components/summary-item/__snapshots__/summary-item.stories.storyshot b/packages/ui/build/storybook/components/summary-item/__snapshots__/summary-item.stories.storyshot index 46f573a2ec..9d6fbce308 100644 --- a/packages/ui/build/storybook/components/summary-item/__snapshots__/summary-item.stories.storyshot +++ b/packages/ui/build/storybook/components/summary-item/__snapshots__/summary-item.stories.storyshot @@ -1,5 +1,39 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Storyshots Components/SummaryItem Budget Over 1`] = ` +
+ + +
+`; + +exports[`Storyshots Components/SummaryItem Budget Under 1`] = ` +
+ + +
+`; + exports[`Storyshots Components/SummaryItem Loading 1`] = `
diff --git a/packages/ui/src/components/summary-item/summary-item.jsx b/packages/ui/src/components/summary-item/summary-item.jsx index edc0620bce..eff5d7c801 100644 --- a/packages/ui/src/components/summary-item/summary-item.jsx +++ b/packages/ui/src/components/summary-item/summary-item.jsx @@ -3,7 +3,9 @@ import PropTypes from 'prop-types'; import cx from 'classnames'; import { getGlobalMetricType, getMetricRunInfo } from '@bundle-stats/utils'; +import { Icon } from '../../ui/icon'; import { Popover } from '../../ui/popover'; +import { Tooltip } from '../../ui/tooltip'; import { Skeleton } from '../../ui/skeleton'; import { Stack } from '../../layout/stack'; import { FlexStack } from '../../layout/flex-stack'; @@ -40,6 +42,48 @@ MetricInfo.defaultProps = { url: '', }; +const BudgetInfo = ({ className = '', budget, metric }) => { + const rootClassName = cx( + css.budgetIcon, + budget.overBudget ? css.budgetIconWarning : css.budgetIconSuccess, + className, + ); + + return ( + + {`Value is ${budget.overBudget ? 'over' : 'under'} `} + {metric.formatter(budget.budget)} + {` budget`} + + } + > + + + ); +}; + +BudgetInfo.propTypes = { + budget: PropTypes.shape({ + value: PropTypes.number, + budget: PropTypes.number, + overBudget: PropTypes.bool, + }).isRequired, + metric: PropTypes.shape({ + formatter: PropTypes.func, + }).isRequired, + className: PropTypes.string, +}; + +BudgetInfo.defaultProps = { + className: '', +}; + export const SummaryItem = ({ className, as: Component, @@ -49,6 +93,7 @@ export const SummaryItem = ({ loading, showDelta, showMetricDescription, + budget, ...props }) => { const { baseline, current } = data || { baseline: 0, current: 0 }; @@ -64,18 +109,22 @@ export const SummaryItem = ({ showMetricDescription && css.showMetricDescription, showMetricDescriptionTooltip && css.showMetricDescription, showDelta && css.showDelta, + budget?.overBudget && css.budgetOver, + budget?.overBudget === false && css.budgetUnder, ); return ( - {metric.label} + {metric.label} {showMetricDescriptionTooltip && ( )} + + {budget && } @@ -117,6 +166,7 @@ SummaryItem.defaultProps = { loading: false, showMetricDescription: false, showDelta: true, + budget: undefined, }; SummaryItem.propTypes = { @@ -143,4 +193,11 @@ SummaryItem.propTypes = { /** Show delta */ showDelta: PropTypes.bool, + + /** Budget data */ + budget: PropTypes.shape({ + value: PropTypes.number, + budget: PropTypes.number, + overBudget: PropTypes.bool, + }), }; diff --git a/packages/ui/src/components/summary-item/summary-item.module.css b/packages/ui/src/components/summary-item/summary-item.module.css index 9466fbedfa..e13db8d10e 100644 --- a/packages/ui/src/components/summary-item/summary-item.module.css +++ b/packages/ui/src/components/summary-item/summary-item.module.css @@ -8,6 +8,10 @@ white-space: nowrap; } +.titleLabel { + flex: 0 0 auto; +} + .readMoreBtn { appearance: none; padding: 0; @@ -27,6 +31,11 @@ text-decoration: none; } +.budgetIcon { + flex: 0 0 auto; + margin-left: auto !important; +} + .currentMetric { display: block; color: var(--color-heading); @@ -56,6 +65,30 @@ width: 5em; } +/* Budget over */ +.budgetOver .budgetIcon { + color: var(--color-danger-light); +} + +.budgetOver .budgetIcon:hover, +.budgetOver .budgetIcon:focus, +.budgetOver .budgetIcon:active +{ + color: var(--color-danger); +} + +/* Budget under */ +.budgetUnder .budgetIcon { + color: var(--color-success-light); +} + +.budgetUnder .budgetIcon:hover, +.budgetUnder .budgetIcon:focus, +.budgetUnder .budgetIcon:active +{ + color: var(--color-success); +} + /* Size large */ .large .currentMetric { font-size: var(--size-xxxlarge); diff --git a/packages/ui/src/components/summary-item/summary-item.stories.jsx b/packages/ui/src/components/summary-item/summary-item.stories.jsx index ce48fec9bf..26c9aa98f9 100644 --- a/packages/ui/src/components/summary-item/summary-item.stories.jsx +++ b/packages/ui/src/components/summary-item/summary-item.stories.jsx @@ -5,53 +5,69 @@ import { SummaryItem } from './summary-item'; export default { title: 'Components/SummaryItem', component: SummaryItem, -}; - -export const Standard = () => ( - -); - -export const SizeLarge = () => ( - ( +
+ +
+ ), + ], + args: { + loading: false, + id: 'webpack.totalSizeByTypeALL', + data: { current: 120 * 1000, baseline: 100 * 1000, - }} - /> -); - -export const ShowMetricDescription = () => ( - -); - -export const ShowDeltaFalse = () => ( - -); + }, + }, +}; + +const Template = (args) => ; + +export const Standard = Template.bind(); + +export const SizeLarge = Template.bind(); + +SizeLarge.args = { + size: 'large', +}; + +export const ShowMetricDescription = Template.bind(); -export const Loading = () => ; +ShowMetricDescription.args = { + showMetricDescription: true, +}; + +export const ShowDeltaFalse = Template.bind(); + +ShowDeltaFalse.args = { + showDelta: false, +}; + +export const BudgetOver = Template.bind(); + +BudgetOver.args = { + showMetricDescription: true, + budget: { + value: 120 * 1000, + budget: 100 * 1000, + overBudget: true, + }, +}; + +export const BudgetUnder = Template.bind(); + +BudgetUnder.args = { + showMetricDescription: true, + budget: { + value: 120 * 1000, + budget: 120 * 1024, + overBudget: false, + }, +}; + +export const Loading = Template.bind(); + +Loading.args = { + loading: true, +};