diff options
Diffstat (limited to 'server/sonar-web/design-system/src/sonar-aligned')
8 files changed, 361 insertions, 0 deletions
diff --git a/server/sonar-web/design-system/src/sonar-aligned/components/Card.tsx b/server/sonar-web/design-system/src/sonar-aligned/components/Card.tsx new file mode 100644 index 00000000000..a8f7c8ce929 --- /dev/null +++ b/server/sonar-web/design-system/src/sonar-aligned/components/Card.tsx @@ -0,0 +1,77 @@ +/* + * 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 * as React from 'react'; +import tw from 'twin.macro'; +import { BasicSeparator } from '../../components/Separator'; +import { themeBorder, themeColor } from '../../helpers/theme'; + +interface CardProps extends React.HTMLAttributes<HTMLDivElement> { + children: React.ReactNode; +} + +export function Card(props: Readonly<CardProps>) { + const { children, ...rest } = props; + + return <CardStyled {...rest}>{children}</CardStyled>; +} + +export function GreyCard(props: Readonly<CardProps>) { + const { children, ...rest } = props; + + return <GreyCardStyled {...rest}>{children}</GreyCardStyled>; +} + +export function LightGreyCard(props: Readonly<CardProps>) { + const { children, ...rest } = props; + + return <LightGreyCardStyled {...rest}>{children}</LightGreyCardStyled>; +} + +export function LightGreyCardTitle({ children }: Readonly<React.PropsWithChildren>) { + return ( + <> + <div className="sw-flex sw-items-center sw-justify-between sw-w-full sw-mb-4 sw-min-h-6"> + {children} + </div> + <BasicSeparator className="sw--mx-6 sw-my-0" /> + </> + ); +} + +export const CardWithPrimaryBackground = styled(Card)` + background-color: ${themeColor('backgroundPrimary')}; +`; + +const CardStyled = styled.div` + background-color: ${themeColor('backgroundSecondary')}; + border: ${themeBorder('default', 'projectCardBorder')}; + + ${tw`sw-p-6`}; + ${tw`sw-rounded-1`}; +`; + +const LightGreyCardStyled = styled(CardStyled)` + border: ${themeBorder('default')}; +`; + +const GreyCardStyled = styled(CardStyled)` + border: ${themeBorder('default', 'almCardBorder')}; +`; 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`}; +`; diff --git a/server/sonar-web/design-system/src/sonar-aligned/components/__tests__/Card-test.tsx b/server/sonar-web/design-system/src/sonar-aligned/components/__tests__/Card-test.tsx new file mode 100644 index 00000000000..817af9d4da6 --- /dev/null +++ b/server/sonar-web/design-system/src/sonar-aligned/components/__tests__/Card-test.tsx @@ -0,0 +1,45 @@ +/* + * 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 { screen } from '@testing-library/react'; +import { render } from '../../../helpers/testUtils'; +import { Card, GreyCard, LightGreyCard } from '../Card'; + +it('renders card correctly', () => { + render(<Card>Hello</Card>); + const cardContent = screen.getByText('Hello'); + expect(cardContent).toHaveStyle({ + border: '1px solid rgb(225,230,243)', + 'background-color': 'rgb(255,255,255)', + }); +}); + +it.each([Card, GreyCard, LightGreyCard])( + 'renders %p correctly with classNames', + (CardComponent) => { + render( + <CardComponent className="sw-bg-black sw-border-8" role="tabpanel"> + Hello + </CardComponent>, + ); + const cardContent = screen.getByText('Hello'); + expect(cardContent).toHaveClass('sw-bg-black sw-border-8'); + expect(cardContent).toHaveAttribute('role', 'tabpanel'); + }, +); diff --git a/server/sonar-web/design-system/src/sonar-aligned/components/__tests__/MetricsRatingBadge-test.tsx b/server/sonar-web/design-system/src/sonar-aligned/components/__tests__/MetricsRatingBadge-test.tsx new file mode 100644 index 00000000000..8342ab1ca6c --- /dev/null +++ b/server/sonar-web/design-system/src/sonar-aligned/components/__tests__/MetricsRatingBadge-test.tsx @@ -0,0 +1,38 @@ +/* + * 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 { screen } from '@testing-library/react'; +import { render } from '../../../helpers/testUtils'; +import { FCProps } from '../../../types/misc'; + +import { MetricsRatingBadge } from '../MetricsRatingBadge'; + +it('should display RatingIndicator', () => { + setupWithProps(); + expect(screen.getByLabelText('New label')).toBeInTheDocument(); +}); + +it('should display RatingIndicator with value', () => { + setupWithProps({ rating: 'A' }); + expect(screen.getByText('A')).toBeInTheDocument(); +}); + +function setupWithProps(props: Partial<FCProps<typeof MetricsRatingBadge>> = {}) { + return render(<MetricsRatingBadge label="New label" {...props} />); +} diff --git a/server/sonar-web/design-system/src/sonar-aligned/components/index.ts b/server/sonar-web/design-system/src/sonar-aligned/components/index.ts new file mode 100644 index 00000000000..4aff4e3e703 --- /dev/null +++ b/server/sonar-web/design-system/src/sonar-aligned/components/index.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +export * from './Card'; +export * from './MetricsRatingBadge'; diff --git a/server/sonar-web/design-system/src/sonar-aligned/index.ts b/server/sonar-web/design-system/src/sonar-aligned/index.ts new file mode 100644 index 00000000000..48fc39c2122 --- /dev/null +++ b/server/sonar-web/design-system/src/sonar-aligned/index.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +export * from './components'; +export * from './types'; diff --git a/server/sonar-web/design-system/src/sonar-aligned/types/index.ts b/server/sonar-web/design-system/src/sonar-aligned/types/index.ts new file mode 100644 index 00000000000..076ba52f860 --- /dev/null +++ b/server/sonar-web/design-system/src/sonar-aligned/types/index.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +export * from './measures'; diff --git a/server/sonar-web/design-system/src/sonar-aligned/types/measures.ts b/server/sonar-web/design-system/src/sonar-aligned/types/measures.ts new file mode 100644 index 00000000000..b7e402a65f7 --- /dev/null +++ b/server/sonar-web/design-system/src/sonar-aligned/types/measures.ts @@ -0,0 +1,29 @@ +/* + * 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. + */ + +export enum RatingEnum { + A = 'A', + B = 'B', + C = 'C', + D = 'D', + E = 'E', +} + +export type RatingLabel = keyof typeof RatingEnum; |