aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx')
-rw-r--r--server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx107
1 files changed, 107 insertions, 0 deletions
diff --git a/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx b/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx
new file mode 100644
index 00000000000..9bdae72f604
--- /dev/null
+++ b/server/sonar-web/design-system/src/sonar-aligned/components/MetricsRatingBadge.tsx
@@ -0,0 +1,107 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import styled from '@emotion/styled';
+import tw from 'twin.macro';
+import { getProp, themeColor, themeContrast } from '../../helpers/theme';
+import { RatingLabel } from '../types/measures';
+
+type sizeType = keyof typeof SIZE_MAPPING;
+interface Props extends React.AriaAttributes {
+ className?: string;
+ label?: string;
+ rating?: RatingLabel;
+ size?: sizeType;
+}
+
+const SIZE_MAPPING = {
+ xs: '1rem',
+ sm: '1.5rem',
+ md: '2rem',
+ lg: '2.8rem',
+ xl: '4rem',
+};
+
+export function MetricsRatingBadge({
+ className,
+ size = 'sm',
+ label,
+ rating,
+ ...ariaAttrs
+}: Readonly<Props>) {
+ if (!rating) {
+ return (
+ <StyledNoRatingBadge
+ aria-label={label}
+ className={className}
+ size={SIZE_MAPPING[size]}
+ {...ariaAttrs}
+ >
+ —
+ </StyledNoRatingBadge>
+ );
+ }
+ return (
+ <MetricsRatingBadgeStyled
+ aria-label={label}
+ className={className}
+ rating={rating}
+ size={SIZE_MAPPING[size]}
+ {...ariaAttrs}
+ >
+ {rating}
+ </MetricsRatingBadgeStyled>
+ );
+}
+
+const StyledNoRatingBadge = styled.div<{ size: string }>`
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+
+ width: ${getProp('size')};
+ height: ${getProp('size')};
+`;
+
+const getFontSize = (size: string) => {
+ switch (size) {
+ case '2rem':
+ return '0.875rem';
+ case '4rem':
+ return '1.5rem';
+ default:
+ return '0.75rem';
+ }
+};
+
+const MetricsRatingBadgeStyled = styled.div<{ rating: RatingLabel; size: string }>`
+ width: ${getProp('size')};
+ height: ${getProp('size')};
+ color: ${({ rating }) => themeContrast(`rating.${rating}`)};
+ font-size: ${({ size }) => getFontSize(size)};
+ background-color: ${({ rating }) => themeColor(`rating.${rating}`)};
+ user-select: none;
+
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+
+ ${tw`sw-rounded-pill`};
+ ${tw`sw-font-semibold`};
+`;