Ver código fonte

SONAR-21164 - Add prettier into design system build

tags/10.4.0.87286
Kevin Silva 5 meses atrás
pai
commit
83325c0040
64 arquivos alterados com 190 adições e 172 exclusões
  1. 4
    1
      server/sonar-web/design-system/package.json
  2. 3
    1
      server/sonar-web/design-system/src/components/Accordion.tsx
  3. 1
    1
      server/sonar-web/design-system/src/components/Breadcrumbs.tsx
  4. 10
    10
      server/sonar-web/design-system/src/components/BubbleChart.tsx
  5. 1
    1
      server/sonar-web/design-system/src/components/CodeSnippet.tsx
  6. 17
    16
      server/sonar-web/design-system/src/components/InteractiveIcon.tsx
  7. 1
    1
      server/sonar-web/design-system/src/components/LocationMarker.tsx
  8. 1
    1
      server/sonar-web/design-system/src/components/NavBarTabs.tsx
  9. 1
    1
      server/sonar-web/design-system/src/components/NavLink.tsx
  10. 1
    1
      server/sonar-web/design-system/src/components/SelectionCard.tsx
  11. 26
    20
      server/sonar-web/design-system/src/components/Tooltip.tsx
  12. 3
    3
      server/sonar-web/design-system/src/components/__tests__/Banner-test.tsx
  13. 1
    1
      server/sonar-web/design-system/src/components/__tests__/BarChart-test.tsx
  14. 1
    1
      server/sonar-web/design-system/src/components/__tests__/Breadcrumbs-test.tsx
  15. 1
    1
      server/sonar-web/design-system/src/components/__tests__/BubbleChart-test.tsx
  16. 2
    2
      server/sonar-web/design-system/src/components/__tests__/Card-test.tsx
  17. 1
    1
      server/sonar-web/design-system/src/components/__tests__/CodeSnippet-test.tsx
  18. 3
    3
      server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx
  19. 2
    2
      server/sonar-web/design-system/src/components/__tests__/DropdownMenu-test.tsx
  20. 1
    1
      server/sonar-web/design-system/src/components/__tests__/DuplicationsIndicator-test.tsx
  21. 2
    2
      server/sonar-web/design-system/src/components/__tests__/ExecutionFlowAccordion-test.tsx
  22. 1
    1
      server/sonar-web/design-system/src/components/__tests__/FacetBox-test.tsx
  23. 1
    1
      server/sonar-web/design-system/src/components/__tests__/FacetItem-test.tsx
  24. 1
    1
      server/sonar-web/design-system/src/components/__tests__/FavoriteButton-test.tsx
  25. 1
    1
      server/sonar-web/design-system/src/components/__tests__/HotspotRating-test.tsx
  26. 3
    3
      server/sonar-web/design-system/src/components/__tests__/LineCoverage-test.tsx
  27. 1
    1
      server/sonar-web/design-system/src/components/__tests__/LineFinding-test.tsx
  28. 1
    1
      server/sonar-web/design-system/src/components/__tests__/LineNumber-test.tsx
  29. 2
    8
      server/sonar-web/design-system/src/components/__tests__/LineWrapper-test.tsx
  30. 2
    2
      server/sonar-web/design-system/src/components/__tests__/MainAppBar-test.tsx
  31. 3
    3
      server/sonar-web/design-system/src/components/__tests__/MenuItem-test.tsx
  32. 1
    1
      server/sonar-web/design-system/src/components/__tests__/NavBarTabs-test.tsx
  33. 3
    3
      server/sonar-web/design-system/src/components/__tests__/NavLink-test.tsx
  34. 1
    1
      server/sonar-web/design-system/src/components/__tests__/QualityGateIndicator-test.tsx
  35. 1
    1
      server/sonar-web/design-system/src/components/__tests__/SelectionCard-test.tsx
  36. 7
    7
      server/sonar-web/design-system/src/components/__tests__/Table-test.tsx
  37. 1
    1
      server/sonar-web/design-system/src/components/__tests__/ToggleButton-test.tsx
  38. 5
    5
      server/sonar-web/design-system/src/components/__tests__/Tooltip-test.tsx
  39. 1
    1
      server/sonar-web/design-system/src/components/__tests__/TreeMap-test.tsx
  40. 1
    1
      server/sonar-web/design-system/src/components/__tests__/TutorialStep-test.tsx
  41. 2
    2
      server/sonar-web/design-system/src/components/avatar/__tests__/Avatar-test.tsx
  42. 3
    1
      server/sonar-web/design-system/src/components/buttons/Button.tsx
  43. 1
    1
      server/sonar-web/design-system/src/components/code-line/LineFinding.tsx
  44. 1
    1
      server/sonar-web/design-system/src/components/code-line/LineIssuePointer.tsx
  45. 1
    1
      server/sonar-web/design-system/src/components/code-line/LineMarker.tsx
  46. 2
    2
      server/sonar-web/design-system/src/components/icons/__tests__/Icon-test.tsx
  47. 4
    4
      server/sonar-web/design-system/src/components/input/SearchSelect.tsx
  48. 1
    1
      server/sonar-web/design-system/src/components/input/__tests__/DiscreetSelect-test.tsx
  49. 2
    2
      server/sonar-web/design-system/src/components/input/__tests__/FormField-test.tsx
  50. 1
    1
      server/sonar-web/design-system/src/components/input/__tests__/InputSearch-test.tsx
  51. 1
    1
      server/sonar-web/design-system/src/components/input/__tests__/MultiSelectMenu-test.tsx
  52. 1
    1
      server/sonar-web/design-system/src/components/input/__tests__/RadioButton-test.tsx
  53. 1
    1
      server/sonar-web/design-system/src/components/input/__tests__/SearchSelectControlledInput-test.tsx
  54. 2
    2
      server/sonar-web/design-system/src/components/input/__tests__/SearchSelectDropdown-test.tsx
  55. 1
    1
      server/sonar-web/design-system/src/components/lists/__tests__/NumberedList-test.tsx
  56. 1
    1
      server/sonar-web/design-system/src/components/lists/__tests__/UnorderedList-test.tsx
  57. 3
    3
      server/sonar-web/design-system/src/components/modal/__tests__/Modal-test.tsx
  58. 1
    1
      server/sonar-web/design-system/src/components/subnavigation/__tests__/SubnavigationAccordion-test.tsx
  59. 1
    1
      server/sonar-web/design-system/src/components/subnavigation/__tests__/SubnavigationItem-test.tsx
  60. 19
    19
      server/sonar-web/design-system/src/helpers/__tests__/theme-test.ts
  61. 1
    1
      server/sonar-web/design-system/src/helpers/keyboard.ts
  62. 7
    7
      server/sonar-web/design-system/src/helpers/positioning.ts
  63. 3
    3
      server/sonar-web/design-system/src/helpers/theme.ts
  64. 10
    0
      server/sonar-web/yarn.lock

+ 4
- 1
server/sonar-web/design-system/package.json Ver arquivo

@@ -4,6 +4,8 @@
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"format": "prettier --write --list-different \"src/**/*.{ts,tsx}\"",
"format-check": "prettier --list-different \"src/**/*.{ts,tsx}\"",
"build": "yarn lint && yarn ts-check && vite build",
"build:no-checks": "vite build",
"build-release": "yarn install --immutable && yarn build",
@@ -11,7 +13,7 @@
"lint-report-ci": "yarn install --immutable && eslint --ext js,ts,tsx -f json -o eslint-report/eslint-report.json src || yarn lint",
"test": "jest",
"ts-check": "tsc --noEmit",
"validate-ci": "yarn install --immutable && yarn ts-check && yarn test --coverage --ci"
"validate-ci": "yarn install --immutable && yarn ts-check && yarn format-check && yarn test --coverage --ci"
},
"devDependencies": {
"@babel/core": "7.23.2",
@@ -44,6 +46,7 @@
"postcss": "8.4.31",
"postcss-calc": "9.0.1",
"postcss-custom-properties": "12.1.11",
"prettier": "^3.1.0",
"twin.macro": "3.4.0",
"typescript": "5.2.2",
"vite": "4.5.0",

+ 3
- 1
server/sonar-web/design-system/src/components/Accordion.tsx Ver arquivo

@@ -78,7 +78,9 @@ const accordionStyle = (props: ThemedProps) => css`
border: ${themeBorder('default', 'buttonSecondaryBorder')(props)};
color: ${themeContrast('buttonSecondary')(props)};
background-color: ${themeColor('buttonSecondary')(props)};
transition: background-color 0.2s ease, outline 0.2s ease;
transition:
background-color 0.2s ease,
outline 0.2s ease;

& > button {
${tw`sw-body-sm-highlight`}

+ 1
- 1
server/sonar-web/design-system/src/components/Breadcrumbs.tsx Ver arquivo

@@ -122,7 +122,7 @@ export function Breadcrumbs(props: Props) {
overlay={modifiedChildren[index].props.children as React.ReactNode}
>
{modifiedChildren[index]}
</Tooltip>
</Tooltip>,
);
} else if (
isLastBreadcrumb ||

+ 10
- 10
server/sonar-web/design-system/src/components/BubbleChart.tsx Ver arquivo

@@ -121,7 +121,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {
k,
});
},
[padding]
[padding],
);

const boundNode = React.useCallback(
@@ -130,7 +130,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {
zoomRef.current = zoom().scaleExtent([1, 10]).on('zoom', zoomed);
select(nodeRef.current).call(zoomRef.current);
},
[zoomed]
[zoomed],
);

const resetZoom = React.useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
@@ -150,7 +150,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {
const dMaxX = maxX > x2 ? maxX - x2 : 0;
return [dMinX, availableWidth - dMaxX];
},
[items]
[items],
);

const getYRange = React.useCallback(
@@ -162,7 +162,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {
const dMaxY = maxY > y1 ? maxY - y1 : 0;
return [availableHeight - dMaxY, dMinY];
},
[items]
[items],
);

const getTicks = React.useCallback(
@@ -176,7 +176,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {
: TICKS_COUNT * zoomAmount;
return scale.ticks(ticksCount);
},
[transform]
[transform],
);

const renderXGrid = React.useCallback(
@@ -202,7 +202,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {

return <g>{lines}</g>;
},
[transform, displayXGrid]
[transform, displayXGrid],
);

const renderYGrid = React.useCallback(
@@ -228,7 +228,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {

return <g>{lines}</g>;
},
[displayYGrid, transform]
[displayYGrid, transform],
);

const renderXTicks = React.useCallback(
@@ -252,7 +252,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {

return <g>{ticks}</g>;
},
[displayXTicks, formatXTick, transform]
[displayXTicks, formatXTick, transform],
);

const renderYTicks = React.useCallback(
@@ -283,7 +283,7 @@ export function BubbleChart<T>(props: BubbleChartProps<T>) {

return <g>{ticks}</g>;
},
[displayYTicks, formatYTick, transform]
[displayYTicks, formatYTick, transform],
);

const renderChart = (width: number) => {
@@ -406,7 +406,7 @@ function Bubble<T>(props: BubbleProps<T>) {
event.preventDefault();
onClick?.(data);
},
[data, onClick]
[data, onClick],
);

const circle = (

+ 1
- 1
server/sonar-web/design-system/src/components/CodeSnippet.tsx Ver arquivo

@@ -70,7 +70,7 @@ export function CodeSnippet(props: Props) {
'code-snippet-simple-oneline': isSimpleOneLine,
},
className,
'fs-mask'
'fs-mask',
)}
>
{!noCopy && copyButton}

+ 17
- 16
server/sonar-web/design-system/src/components/InteractiveIcon.tsx Ver arquivo

@@ -107,7 +107,10 @@ const buttonIconStyle = (props: ThemedProps & { size: InteractiveIconSize }) =>
text-decoration: none;
color: var(--color);
background-color: var(--background);
transition: background-color 0.2s ease, outline 0.2s ease, color 0.2s ease;
transition:
background-color 0.2s ease,
outline 0.2s ease,
color 0.2s ease;

${tw`sw-inline-flex sw-items-center sw-justify-center`}
${tw`sw-cursor-pointer`}
@@ -158,11 +161,10 @@ export const InteractiveIcon: React.FC<React.PropsWithChildren<InteractiveIconPr
--focus: ${themeColor('interactiveIconFocus', OPACITY_20_PERCENT)};
`;

export const DiscreetInteractiveIcon: React.FC<
React.PropsWithChildren<InteractiveIconProps>
> = styled(InteractiveIcon)`
--color: ${themeColor('discreetInteractiveIcon')};
`;
export const DiscreetInteractiveIcon: React.FC<React.PropsWithChildren<InteractiveIconProps>> =
styled(InteractiveIcon)`
--color: ${themeColor('discreetInteractiveIcon')};
`;

export const DestructiveIcon: React.FC<React.PropsWithChildren<InteractiveIconProps>> = styled(
InteractiveIconBase,
@@ -174,14 +176,13 @@ export const DestructiveIcon: React.FC<React.PropsWithChildren<InteractiveIconPr
--focus: ${themeColor('destructiveIconFocus', OPACITY_20_PERCENT)};
`;

export const DismissProductNewsIcon: React.FC<
React.PropsWithChildren<InteractiveIconProps>
> = styled(InteractiveIcon)`
--background: ${themeColor('productNews')};
--backgroundHover: ${themeColor('productNewsHover')};
--color: ${themeContrast('productNews')};
--colorHover: ${themeContrast('productNewsHover')};
--focus: ${themeColor('interactiveIconFocus', OPACITY_20_PERCENT)};
export const DismissProductNewsIcon: React.FC<React.PropsWithChildren<InteractiveIconProps>> =
styled(InteractiveIcon)`
--background: ${themeColor('productNews')};
--backgroundHover: ${themeColor('productNewsHover')};
--color: ${themeContrast('productNews')};
--colorHover: ${themeContrast('productNewsHover')};
--focus: ${themeColor('interactiveIconFocus', OPACITY_20_PERCENT)};

height: 28px;
`;
height: 28px;
`;

+ 1
- 1
server/sonar-web/design-system/src/components/LocationMarker.tsx Ver arquivo

@@ -34,7 +34,7 @@ interface Props {

function InternalLocationMarker(
{ className, onClick, text, selected }: Props,
ref: LegacyRef<HTMLDivElement>
ref: LegacyRef<HTMLDivElement>,
) {
return (
<StyledMarker

+ 1
- 1
server/sonar-web/design-system/src/components/NavBarTabs.tsx Ver arquivo

@@ -58,7 +58,7 @@ export function NavBarTabLink(props: NavBarTabLinkProps) {
classNames(
'sw-flex sw-items-center',
{ active: isDefined(active) ? active : isActive },
className
className,
)
}
{...linkProps}

+ 1
- 1
server/sonar-web/design-system/src/components/NavLink.tsx Ver arquivo

@@ -60,7 +60,7 @@ function NavLinkWithRef(props: NavLinkProps, ref: React.ForwardedRef<HTMLAnchorE
onClick(event);
}
},
[onClick, blurAfterClick, preventDefault, stopPropagation, disabled]
[onClick, blurAfterClick, preventDefault, stopPropagation, disabled],
);

return (

+ 1
- 1
server/sonar-web/design-system/src/components/SelectionCard.tsx Ver arquivo

@@ -68,7 +68,7 @@ export function SelectionCard(props: SelectionCardProps) {
disabled,
selected,
},
className
className,
)}
onClick={isActionable && !disabled && !selected ? onClick : undefined}
role={isActionable ? 'radio' : 'presentation'}

+ 26
- 20
server/sonar-web/design-system/src/components/Tooltip.tsx Ver arquivo

@@ -128,7 +128,7 @@ export class TooltipInner extends React.Component<TooltipProps, State> {
// position (which is no longer correct).
this.positionTooltip();
}
}
},
);
}
}
@@ -195,7 +195,7 @@ export class TooltipInner extends React.Component<TooltipProps, State> {

adjustArrowPosition = (
placement: PopupPlacement,
{ leftFix, topFix, height, width }: Measurements
{ leftFix, topFix, height, width }: Measurements,
) => {
switch (placement) {
case PopupPlacement.Left:
@@ -223,7 +223,7 @@ export class TooltipInner extends React.Component<TooltipProps, State> {
const { height, left, leftFix, top, topFix, width } = popupPositioning(
toggleNode,
this.tooltipNode,
this.getPlacement()
this.getPlacement(),
);

// save width and height (and later set in `render`) to avoid resizing the popup element,
@@ -253,18 +253,21 @@ export class TooltipInner extends React.Component<TooltipProps, State> {
};

handlePointerEnter = () => {
this.mouseEnterTimeout = window.setTimeout(() => {
// for some reason even after the `this.mouseEnterTimeout` is cleared, it still triggers
// to workaround this issue, check that its value is not `undefined`
// (if it's `undefined`, it means the timer has been reset)
if (
this.mounted &&
this.props.visible === undefined &&
this.mouseEnterTimeout !== undefined
) {
this.setState({ visible: true });
}
}, (this.props.mouseEnterDelay ?? 0) * MILLISECONDS_IN_A_SECOND);
this.mouseEnterTimeout = window.setTimeout(
() => {
// for some reason even after the `this.mouseEnterTimeout` is cleared, it still triggers
// to workaround this issue, check that its value is not `undefined`
// (if it's `undefined`, it means the timer has been reset)
if (
this.mounted &&
this.props.visible === undefined &&
this.mouseEnterTimeout !== undefined
) {
this.setState({ visible: true });
}
},
(this.props.mouseEnterDelay ?? 0) * MILLISECONDS_IN_A_SECOND,
);

if (this.props.onShow) {
this.props.onShow();
@@ -278,11 +281,14 @@ export class TooltipInner extends React.Component<TooltipProps, State> {
}

if (!this.mouseIn) {
this.mouseLeaveTimeout = window.setTimeout(() => {
if (this.mounted && this.props.visible === undefined && !this.mouseIn) {
this.setState({ visible: false });
}
}, (this.props.mouseLeaveDelay ?? 0) * MILLISECONDS_IN_A_SECOND);
this.mouseLeaveTimeout = window.setTimeout(
() => {
if (this.mounted && this.props.visible === undefined && !this.mouseIn) {
this.setState({ visible: false });
}
},
(this.props.mouseLeaveDelay ?? 0) * MILLISECONDS_IN_A_SECOND,
);

if (this.props.onHide) {
this.props.onHide();

+ 3
- 3
server/sonar-web/design-system/src/components/__tests__/Banner-test.tsx Ver arquivo

@@ -29,13 +29,13 @@ it('should render with close button', async () => {
expect(
screen.getByRole('button', {
name: 'dismiss',
})
}),
).toBeVisible();

await user.click(
screen.getByRole('button', {
name: 'dismiss',
})
}),
);

expect(onDismiss).toHaveBeenCalledTimes(1);
@@ -45,6 +45,6 @@ function setupWithProps(props: Partial<FCProps<typeof Banner>> = {}) {
return renderWithContext(
<Banner {...props} variant="warning">
<Note className="sw-body-sm">{props.children ?? 'Test Message'}</Note>
</Banner>
</Banner>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/BarChart-test.tsx Ver arquivo

@@ -58,6 +58,6 @@ function renderChart(overrides: Partial<FCProps<typeof BarChart>> = {}) {
onBarClick={jest.fn()}
width={200}
{...overrides}
/>
/>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/Breadcrumbs-test.tsx Ver arquivo

@@ -33,7 +33,7 @@ it('should display three breadcrumbs correctly', () => {
<HoverLink to="/first">first</HoverLink>
<HoverLink to="/second">second</HoverLink>
<HoverLink to="/third">third</HoverLink>
</BreadcrumbsFullWidth>
</BreadcrumbsFullWidth>,
);

expect(screen.getAllByRole('link').length).toBe(3);

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/BubbleChart-test.tsx Ver arquivo

@@ -86,6 +86,6 @@ function renderBubbleChart(props: Partial<FCProps<typeof BubbleChart>> = {}) {
]}
padding={[0, 0, 0, 0]}
{...props}
/>
/>,
);
}

+ 2
- 2
server/sonar-web/design-system/src/components/__tests__/Card-test.tsx Ver arquivo

@@ -35,7 +35,7 @@ it('renders card correctly with classNames', () => {
render(
<Card className="sw-bg-black sw-border-8" role="tabpanel">
Hello
</Card>
</Card>,
);
const cardContent = screen.getByText('Hello');
expect(cardContent).toHaveClass('sw-bg-black sw-border-8');
@@ -46,7 +46,7 @@ it('renders grey card correctly with classNames', () => {
render(
<GreyCard className="sw-bg-black sw-border-8" role="tabpanel">
Hello
</GreyCard>
</GreyCard>,
);
const cardContent = screen.getByText('Hello');
expect(cardContent).toHaveClass('sw-bg-black sw-border-8');

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/CodeSnippet-test.tsx Ver arquivo

@@ -46,6 +46,6 @@ function setupWithProps(props: Partial<FCProps<typeof CodeSnippet>> = {}) {
return renderWithContext(
<HelmetProvider>
<CodeSnippet snippet={'foo\nbar'} {...props} />
</HelmetProvider>
</HelmetProvider>,
);
}

+ 3
- 3
server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx Ver arquivo

@@ -29,7 +29,7 @@ it('renders correctly with no code', () => {

<p>There's no code here.</p>
`}
/>
/>,
);

// eslint-disable-next-line testing-library/no-node-access
@@ -45,7 +45,7 @@ it('renders correctly with code', () => {
<p>There's some <code>"code"</code> here.</p>
`}
language="typescript"
/>
/>,
);

// eslint-disable-next-line testing-library/no-node-access
@@ -61,7 +61,7 @@ it('handles html code snippets', () => {
htmlAsString={
'\u003ch4\u003eNoncompliant code example\u003c/h4\u003e\n\u003cpre data-diff-id\u003d"1" data-diff-type\u003d"noncompliant"\u003e\npublic void Method(MyObject myObject)\n{\n if (myObject is null)\n {\n new MyObject(); // Noncompliant\n }\n\n if (myObject.IsCorrupted)\n {\n new ArgumentException($"{nameof(myObject)} is corrupted"); // Noncompliant\n }\n\n // ...\n}\n\u003c/pre\u003e\n\u003ch4\u003eCompliant solution\u003c/h4\u003e\n\u003cpre data-diff-id\u003d"1" data-diff-type\u003d"compliant"\u003e\npublic void Method(MyObject myObject)\n{\n if (myObject is null)\n {\n myObject \u003d new MyObject(); // Compliant\n }\n\n if (myObject.IsCorrupted)\n {\n throw new ArgumentException($"{nameof(myObject)} is corrupted"); // Compliant\n }\n\n // ...\n}\n\u003c/pre\u003e'
}
/>
/>,
);

expect(container.querySelectorAll('pre')).toHaveLength(2);

+ 2
- 2
server/sonar-web/design-system/src/components/__tests__/DropdownMenu-test.tsx Ver arquivo

@@ -57,7 +57,7 @@ it('menu items should work with tooltips', async () => {
<ItemButton onClick={jest.fn()}>button</ItemButton>
</Tooltip>,
{},
{ delay: null }
{ delay: null },
);

expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
@@ -103,6 +103,6 @@ function renderDropdownMenu() {
<ItemRadioButton checked={false} onCheck={noop} value="radios">
Radio item
</ItemRadioButton>
</DropdownMenu>
</DropdownMenu>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/DuplicationsIndicator-test.tsx Ver arquivo

@@ -35,7 +35,7 @@ it.each(['A', 'B', 'C', 'D', 'E', 'F'])(
(variant: DuplicationLabel) => {
setupWithProps({ rating: variant });
expect(screen.getByRole('img', { hidden: true })).toMatchSnapshot();
}
},
);

function setupWithProps(props: Partial<FCProps<typeof DuplicationsIndicator>> = {}) {

+ 2
- 2
server/sonar-web/design-system/src/components/__tests__/ExecutionFlowAccordion-test.tsx Ver arquivo

@@ -33,11 +33,11 @@ it('should render correctly expanded', () => {

function renderExecutionFlowAccordion(
props: Partial<FCProps<typeof ExecutionFlowAccordion>> = {},
children?: React.ReactNode
children?: React.ReactNode,
) {
return render(
<ExecutionFlowAccordion header="header" id="id" {...props}>
{children}
</ExecutionFlowAccordion>
</ExecutionFlowAccordion>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/FacetBox-test.tsx Ver arquivo

@@ -69,6 +69,6 @@ function renderComponent({ children, ...props }: Partial<FacetBoxProps> = {}) {
return renderWithContext(
<FacetBox name="Test FacetBox" {...props}>
{children}
</FacetBox>
</FacetBox>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/FacetItem-test.tsx Ver arquivo

@@ -70,6 +70,6 @@ it('should not add an aria label if the name is not a string', () => {

function renderComponent(props: Partial<FacetItemProps> = {}) {
return render(
<BaseFacetItem name="Test facet item" onClick={jest.fn()} value="Value" {...props} />
<BaseFacetItem name="Test facet item" onClick={jest.fn()} value="Value" {...props} />,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/FavoriteButton-test.tsx Ver arquivo

@@ -45,6 +45,6 @@ it('should toggle favorite', async () => {

function renderFavoriteButton(props: Partial<FCProps<typeof FavoriteButton>> = {}) {
return render(
<FavoriteButton favorite overlay="label-info" toggleFavorite={jest.fn()} {...props} />
<FavoriteButton favorite overlay="label-info" toggleFavorite={jest.fn()} {...props} />,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/HotspotRating-test.tsx Ver arquivo

@@ -32,7 +32,7 @@ it.each(Object.values(HotspotRatingEnum))(
(rating) => {
renderHotspotRating(rating, 'label');
expect(screen.getByLabelText('label')).toMatchSnapshot();
}
},
);

function renderHotspotRating(rating?: HotspotRatingEnum, label?: string) {

+ 3
- 3
server/sonar-web/design-system/src/components/__tests__/LineCoverage-test.tsx Ver arquivo

@@ -27,7 +27,7 @@ it('should render correctly when covered', () => {

it('should render correctly when uncovered', () => {
expect(
setupWithProps({ lineNumber: 16, coverageStatus: 'uncovered' }).container
setupWithProps({ lineNumber: 16, coverageStatus: 'uncovered' }).container,
).toMatchSnapshot();
});

@@ -36,7 +36,7 @@ it('should render correctly when partially covered without conditions', () => {
setupWithProps({
lineNumber: 16,
coverageStatus: 'partially-covered',
}).container
}).container,
).toMatchSnapshot();
});

@@ -45,7 +45,7 @@ it('should render correctly when partially covered with 5/10 conditions', () =>
setupWithProps({
lineNumber: 16,
coverageStatus: 'partially-covered',
}).container
}).container,
).toMatchSnapshot();
});


+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/LineFinding-test.tsx Ver arquivo

@@ -41,6 +41,6 @@ it('should be clickable when onIssueSelect is provided', async () => {

function setupWithProps(props?: Partial<FCProps<typeof LineFinding>>) {
return render(
<LineFinding issueKey="key" message="message" onIssueSelect={jest.fn()} {...props} />
<LineFinding issueKey="key" message="message" onIssueSelect={jest.fn()} {...props} />,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/LineNumber-test.tsx Ver arquivo

@@ -40,6 +40,6 @@ function setupWithProps(props: Partial<FCProps<typeof LineNumber>> = {}) {
lineNumber={16}
popup={<div>Popup</div>}
{...props}
/>
/>,
);
}

+ 2
- 8
server/sonar-web/design-system/src/components/__tests__/LineWrapper-test.tsx Ver arquivo

@@ -34,7 +34,7 @@ it('should properly setup css grid columns', () => {
});
expect(
setupWithProps({ displayCoverage: false, displaySCM: false, duplicationsCount: 0 }).container
.firstChild
.firstChild,
).toHaveStyle({ '--columns': '44px 26px 1fr' });
});

@@ -45,12 +45,6 @@ it('should set a highlighted background color in css props', () => {

function setupWithProps(props: Partial<FCProps<typeof LineWrapper>> = {}) {
return render(
<LineWrapper
displayCoverage
displaySCM
duplicationsCount={2}
highlighted={false}
{...props}
/>
<LineWrapper displayCoverage displaySCM duplicationsCount={2} highlighted={false} {...props} />,
);
}

+ 2
- 2
server/sonar-web/design-system/src/components/__tests__/MainAppBar-test.tsx Ver arquivo

@@ -49,13 +49,13 @@ it('should render the logo', () => {
function setupWithProps(
props: FCProps<typeof MainAppBar> = {
Logo: () => <img alt="logo" src="http://example.com/logo.png" />,
}
},
) {
return render(
<MemoryRouter initialEntries={['/']}>
<Routes>
<Route element={<MainAppBar {...props} />} path="/" />
</Routes>
</MemoryRouter>
</MemoryRouter>,
);
}

+ 3
- 3
server/sonar-web/design-system/src/components/__tests__/MenuItem-test.tsx Ver arquivo

@@ -28,7 +28,7 @@ it('should render default', () => {
render(
<MainMenuItem>
<a>Hi</a>
</MainMenuItem>
</MainMenuItem>,
);

expect(screen.getByText('Hi')).toHaveStyle({
@@ -41,7 +41,7 @@ it('should render active link', () => {
render(
<MainMenuItem>
<a className="active">Hi</a>
</MainMenuItem>
</MainMenuItem>,
);

expect(screen.getByText('Hi')).toHaveStyle({
@@ -54,7 +54,7 @@ it('should render hovered link', () => {
render(
<MainMenuItem>
<a className="hover">Hi</a>
</MainMenuItem>
</MainMenuItem>,
);

expect(screen.getByText('Hi')).toHaveStyle({

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/NavBarTabs-test.tsx Ver arquivo

@@ -37,7 +37,7 @@ describe('NewNavBarTabs', () => {
return renderWithRouter(
<NavBarTabs>
<NavBarTabLink text="test" to="/summary/new_code" />
</NavBarTabs>
</NavBarTabs>,
);
}
});

+ 3
- 3
server/sonar-web/design-system/src/components/__tests__/NavLink-test.tsx Ver arquivo

@@ -60,7 +60,7 @@ it('should stop propagation when stopPropagation is true', async () => {
const { user } = setupWithMemoryRouter(
<button onClick={buttonOnClick} type="button">
<NavLink stopPropagation to="/second" />
</button>
</button>,
);

await user.click(screen.getByRole('link'));
@@ -71,7 +71,7 @@ it('should stop propagation when stopPropagation is true', async () => {
it('should call onClick when one is passed', async () => {
const onClick = jest.fn();
const { user } = setupWithMemoryRouter(
<NavLink onClick={onClick} stopPropagation to="/second" />
<NavLink onClick={onClick} stopPropagation to="/second" />,
);

await user.click(screen.getByRole('link'));
@@ -108,6 +108,6 @@ const setupWithMemoryRouter = (component: JSX.Element, initialEntries = ['/initi
/>
<Route element={<ShowPath />} path="/second" />
</Routes>
</MemoryRouter>
</MemoryRouter>,
);
};

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/QualityGateIndicator-test.tsx Ver arquivo

@@ -44,7 +44,7 @@ it.each([
setupWithProps({ status, size });

expect(screen.getByRole('status')).toHaveAttribute('width', SIZE_VS_WIDTH[size]);
}
},
);

it('should display tooltip', () => {

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/SelectionCard-test.tsx Ver arquivo

@@ -74,6 +74,6 @@ function renderSelectionCard(props: Partial<FCProps<typeof SelectionCard>> = {})
title="Selection Card"
titleInfo="info"
{...props}
/>
/>,
);
}

+ 7
- 7
server/sonar-web/design-system/src/components/__tests__/Table-test.tsx Ver arquivo

@@ -68,38 +68,38 @@ it('check that the html structure and style is correct for a regular table', ()

// Rows should have accessible attributes
expect(
screen.getByRole('row', { name: 'ContentCellHeader NumericalCellHeader CheckboxCellHeader' })
screen.getByRole('row', { name: 'ContentCellHeader NumericalCellHeader CheckboxCellHeader' }),
).toBeInTheDocument();
expect(
screen.getByRole('row', {
name: 'ContentCell 1 NumericalCell 1 CheckboxCell 1',
})
}),
).toBeInTheDocument();
expect(
screen.getByRole('row', {
name: 'ContentCell 1 NumericalCell 1 CheckboxCell 1',
})
}),
).not.toHaveAttribute('aria-selected');
expect(
screen.getByRole('row', {
selected: true,
name: 'ContentCell 2 NumericalCell 2 CheckboxCell 2',
})
}),
).toBeInTheDocument();
expect(
screen.getByRole('row', {
name: 'NumericalCell 4 CheckboxCell 4',
})
}),
).toBeInTheDocument();

// Cells should have accessible attributes
expect(screen.getByRole('cell', { name: 'NumericalCell 4' })).toHaveAttribute(
'aria-colindex',
'2'
'2',
);
expect(screen.getByRole('cell', { name: 'CheckboxCell 4' })).toHaveAttribute(
'aria-colindex',
'3'
'3',
);
});


+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/ToggleButton-test.tsx Ver arquivo

@@ -57,7 +57,7 @@ it('should work in tablist mode', () => {
expect(screen.getAllByRole('tab')).toHaveLength(3);
expect(screen.getByRole('tab', { name: 'second' })).toHaveAttribute(
'aria-controls',
getTabPanelId(2)
getTabPanelId(2),
);
});


+ 5
- 5
server/sonar-web/design-system/src/components/__tests__/Tooltip-test.tsx Ver arquivo

@@ -49,7 +49,7 @@ describe('TooltipInner', () => {
const onPointerLeave = jest.fn();
const { user } = setupWithProps(
{ onHide, onShow },
<div onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave} role="note" />
<div onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave} role="note" />,
);

await user.hover(screen.getByRole('note'));
@@ -93,12 +93,12 @@ describe('TooltipInner', () => {

function setupWithProps(
props: Partial<TooltipInner['props']> = {},
children = <div role="note" />
children = <div role="note" />,
) {
return render(
<TooltipInner mouseLeaveDelay={0} overlay={<span id="overlay" />} {...props}>
{children}
</TooltipInner>
</TooltipInner>,
);
}
});
@@ -124,12 +124,12 @@ describe('Tooltip', () => {

function setupWithProps(
props: Partial<FCProps<typeof Tooltip>> = {},
children = <div role="note" />
children = <div role="note" />,
) {
return render(
<Tooltip overlay={<span id="overlay" />} {...props}>
{children}
</Tooltip>
</Tooltip>,
);
}
});

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/TreeMap-test.tsx Ver arquivo

@@ -60,6 +60,6 @@ it('should render correctly and forward click event', async () => {

function renderTreeMap(props: Partial<TreeMapProps<unknown>>) {
return render(
<TreeMap height={100} items={[]} onRectangleClick={jest.fn()} width={100} {...props} />
<TreeMap height={100} items={[]} onRectangleClick={jest.fn()} width={100} {...props} />,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/__tests__/TutorialStep-test.tsx Ver arquivo

@@ -33,6 +33,6 @@ function renderTutorialStep() {
return render(
<TutorialStepList>
<TutorialStep title="This is title">These are children</TutorialStep>
</TutorialStepList>
</TutorialStepList>,
);
}

+ 2
- 2
server/sonar-web/design-system/src/components/avatar/__tests__/Avatar-test.tsx Ver arquivo

@@ -36,7 +36,7 @@ it('should be able to render with hash only', () => {
setupWithProps({ hash: '7daf6c79d4802916d83f6266e24850af' });
expect(screen.getByRole('img')).toHaveAttribute(
'src',
'http://example.com/7daf6c79d4802916d83f6266e24850af.jpg?s=48'
'http://example.com/7daf6c79d4802916d83f6266e24850af.jpg?s=48',
);
});

@@ -64,6 +64,6 @@ it('should display organization avatar correctly', () => {

function setupWithProps(props: Partial<FCProps<typeof Avatar>> = {}) {
return render(
<Avatar enableGravatar gravatarServerUrl={gravatarServerUrl} name="foo" {...props} />
<Avatar enableGravatar gravatarServerUrl={gravatarServerUrl} name="foo" {...props} />,
);
}

+ 3
- 1
server/sonar-web/design-system/src/components/buttons/Button.tsx Ver arquivo

@@ -112,7 +112,9 @@ export const buttonStyle = (props: ThemedProps) => css`
border: var(--border);
color: var(--color);
background-color: var(--background);
transition: background-color 0.2s ease, outline 0.2s ease;
transition:
background-color 0.2s ease,
outline 0.2s ease;

${tw`sw-inline-flex sw-items-center`}
${tw`sw-h-control`}

+ 1
- 1
server/sonar-web/design-system/src/components/code-line/LineFinding.tsx Ver arquivo

@@ -33,7 +33,7 @@ interface Props {

function LineFindingFunc(
{ message, issueKey, selected = true, className, onIssueSelect }: Props,
ref: Ref<HTMLButtonElement>
ref: Ref<HTMLButtonElement>,
) {
return (
<LineFindingStyled

+ 1
- 1
server/sonar-web/design-system/src/components/code-line/LineIssuePointer.tsx Ver arquivo

@@ -37,7 +37,7 @@ export function LineIssuePointer({ issueFindingRef }: Props) {
if (pointerRef.current && issueFindingRef?.current) {
setDistance(
issueFindingRef.current.getBoundingClientRect().top -
pointerRef.current.getBoundingClientRect().bottom
pointerRef.current.getBoundingClientRect().bottom,
);
}
}, [pointerRef, issueFindingRef]);

+ 1
- 1
server/sonar-web/design-system/src/components/code-line/LineMarker.tsx Ver arquivo

@@ -35,7 +35,7 @@ interface Props {

function LineMarkerFunc(
{ hideLocationIndex, index, leading, message, onLocationSelect, selected }: Props,
ref: Ref<HTMLElement>
ref: Ref<HTMLElement>,
) {
const element = useRef<HTMLDivElement | null>(null);
const elementMessage = useRef<HTMLDivElement | null>(null);

+ 2
- 2
server/sonar-web/design-system/src/components/icons/__tests__/Icon-test.tsx Ver arquivo

@@ -26,7 +26,7 @@ it('should render custom icon correctly', () => {
render(
<CustomIcon>
<path d="test" />
</CustomIcon>
</CustomIcon>,
);

expect(screen.queryByRole('img')).not.toBeInTheDocument();
@@ -37,7 +37,7 @@ it('should not be hidden when aria-label is set', () => {
render(
<CustomIcon aria-label="test">
<path d="test" />
</CustomIcon>
</CustomIcon>,
);

expect(screen.getByRole('img')).toBeVisible();

+ 4
- 4
server/sonar-web/design-system/src/components/input/SearchSelect.tsx Ver arquivo

@@ -32,14 +32,14 @@ type SearchSelectProps<
V,
Option extends LabelValueSelectOption<V>,
IsMulti extends boolean = false,
Group extends GroupBase<Option> = GroupBase<Option>
Group extends GroupBase<Option> = GroupBase<Option>,
> = SelectProps<V, Option, IsMulti, Group> & AsyncProps<Option, IsMulti, Group>;

export function SearchSelect<
V,
Option extends LabelValueSelectOption<V>,
IsMulti extends boolean = false,
Group extends GroupBase<Option> = GroupBase<Option>
Group extends GroupBase<Option> = GroupBase<Option>,
>({
size = 'full',
selectRef,
@@ -57,7 +57,7 @@ export function SearchSelect<
control: ({ isDisabled }) =>
classNames(
'sw-border-0 sw-rounded-2 sw-outline-none sw-shadow-none',
isDisabled && 'sw-pointer-events-none sw-cursor-not-allowed'
isDisabled && 'sw-pointer-events-none sw-cursor-not-allowed',
),
indicatorsContainer: () => 'sw-hidden',
input: () => `sw-flex sw-w-full sw-p-0 sw-m-0`,
@@ -85,7 +85,7 @@ export function SearchSelectInput<
V,
Option extends LabelValueSelectOption<V>,
IsMulti extends boolean = false,
Group extends GroupBase<Option> = GroupBase<Option>
Group extends GroupBase<Option> = GroupBase<Option>,
>(props: InputProps<Option, IsMulti, Group>) {
const {
selectProps: { placeholder, isLoading, inputValue, minLength },

+ 1
- 1
server/sonar-web/design-system/src/components/input/__tests__/DiscreetSelect-test.tsx Ver arquivo

@@ -54,6 +54,6 @@ function setupWithProps(props: Partial<FCProps<typeof DiscreetSelect>>) {
setValue={jest.fn()}
value="foo"
{...props}
/>
/>,
);
}

+ 2
- 2
server/sonar-web/design-system/src/components/input/__tests__/FormField-test.tsx Ver arquivo

@@ -36,11 +36,11 @@ it('should render with required and description', () => {

function renderFormField(
props: Partial<FCProps<typeof FormField>> = {},
children: any = <div>Fake input</div>
children: any = <div>Fake input</div>,
) {
return render(
<FormField htmlFor="input" label="Hello" {...props}>
{children}
</FormField>
</FormField>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/input/__tests__/InputSearch-test.tsx Ver arquivo

@@ -83,6 +83,6 @@ function setupWithProps(props: Partial<FCProps<typeof InputSearch>> = {}) {
searchInputAriaLabel=""
value="foo"
{...props}
/>
/>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/input/__tests__/MultiSelectMenu-test.tsx Ver arquivo

@@ -109,6 +109,6 @@ function renderMultiselect(props: Partial<MultiSelectMenu['props']> = {}) {
searchInputAriaLabel="search"
selectedElements={[]}
{...props}
/>
/>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/input/__tests__/RadioButton-test.tsx Ver arquivo

@@ -57,6 +57,6 @@ function setupWithProps(props?: Partial<FCProps<typeof RadioButton>>) {
return render(
<RadioButton checked={false} onCheck={jest.fn()} value="value" {...props}>
foo
</RadioButton>
</RadioButton>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/input/__tests__/SearchSelectControlledInput-test.tsx Ver arquivo

@@ -52,6 +52,6 @@ function setupWithProps(props: Partial<FCProps<typeof InputSearch>> = {}) {
searchInputAriaLabel=""
value="foo"
{...props}
/>
/>,
);
}

+ 2
- 2
server/sonar-web/design-system/src/components/input/__tests__/SearchSelectDropdown-test.tsx Ver arquivo

@@ -31,7 +31,7 @@ const defaultOptions = [

const loadOptions = (
query: string,
cb: (options: Array<LabelValueSelectOption<string>>) => void
cb: (options: Array<LabelValueSelectOption<string>>) => void,
) => {
cb(defaultOptions.filter((o) => o.label.includes(query)));
};
@@ -94,6 +94,6 @@ function renderSearchSelectDropdown(props: Partial<FCProps<typeof SearchSelectDr
loadOptions={loadOptions}
placeholder="search for things"
{...props}
/>
/>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/lists/__tests__/NumberedList-test.tsx Ver arquivo

@@ -27,7 +27,7 @@ it('renders correctly', () => {
<NumberedList>
<NumberedListItem>First item</NumberedListItem>
<NumberedListItem>Second item</NumberedListItem>
</NumberedList>
</NumberedList>,
);
expect(screen.getAllByRole('listitem')).toHaveLength(2);
});

+ 1
- 1
server/sonar-web/design-system/src/components/lists/__tests__/UnorderedList-test.tsx Ver arquivo

@@ -27,7 +27,7 @@ it('renders correctly', () => {
<UnorderedList>
<ListItem>First item</ListItem>
<ListItem>Second item</ListItem>
</UnorderedList>
</UnorderedList>,
);
expect(screen.getAllByRole('listitem')).toHaveLength(2);
});

+ 3
- 3
server/sonar-web/design-system/src/components/modal/__tests__/Modal-test.tsx Ver arquivo

@@ -68,7 +68,7 @@ function setupPredefinedContent(props: Partial<PropsWithSections> = {}) {
onClose={jest.fn()}
secondaryButtonLabel="Close"
{...props}
/>
/>,
);
}

@@ -76,7 +76,7 @@ function setupLooseContent(props: Partial<PropsWithChildren> = {}, children = <d
return renderWithContext(
<Modal onClose={jest.fn()} {...props}>
{children}
</Modal>
</Modal>,
);
}

@@ -85,6 +85,6 @@ function setupLooseContentWithMultipleChildren(props: Partial<PropsWithChildren>
<Modal onClose={jest.fn()} {...props}>
<div>Hello there!</div>
<div>How are you?</div>
</Modal>
</Modal>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/subnavigation/__tests__/SubnavigationAccordion-test.tsx Ver arquivo

@@ -70,6 +70,6 @@ function setupWithProps(props: Partial<FCProps<typeof SubnavigationAccordion>> =
return render(
<SubnavigationAccordion header="Header" id="test" {...props}>
<span>Foo</span>
</SubnavigationAccordion>
</SubnavigationAccordion>,
);
}

+ 1
- 1
server/sonar-web/design-system/src/components/subnavigation/__tests__/SubnavigationItem-test.tsx Ver arquivo

@@ -34,6 +34,6 @@ function setupWithProps(props: Partial<FCProps<typeof SubnavigationItem>> = {})
return render(
<SubnavigationItem active={false} onClick={jest.fn()} value="foo" {...props}>
<button type="button">Foo</button>
</SubnavigationItem>
</SubnavigationItem>,
);
}

+ 19
- 19
server/sonar-web/design-system/src/helpers/__tests__/theme-test.ts Ver arquivo

@@ -33,13 +33,13 @@ describe('getProp', () => {
describe('themeColor', () => {
it('should work for light theme', () => {
expect(ThemeHelper.themeColor('backgroundPrimary')({ theme: lightTheme })).toEqual(
'rgb(252,252,253)'
'rgb(252,252,253)',
);
});

it('should work with a theme-defined opacity', () => {
expect(ThemeHelper.themeColor('bannerIconHover')({ theme: lightTheme })).toEqual(
'rgba(217,45,32,0.2)'
'rgba(217,45,32,0.2)',
);
});

@@ -53,13 +53,13 @@ describe('themeColor', () => {
ThemeHelper.themeColor(ThemeHelper.themeContrast('backgroundPrimary')({ theme: lightTheme }))(
{
theme: lightTheme,
}
)
},
),
).toEqual('rgb(8,9,12)');
expect(
ThemeHelper.themeColor(ThemeHelper.themeAvatarColor('luke')({ theme: lightTheme }))({
theme: lightTheme,
})
}),
).toEqual('rgb(209,215,254)');
});
});
@@ -67,7 +67,7 @@ describe('themeColor', () => {
describe('themeContrast', () => {
it('should work for light theme', () => {
expect(ThemeHelper.themeContrast('backgroundPrimary')({ theme: lightTheme })).toEqual(
'rgb(8,9,12)'
'rgb(8,9,12)',
);
});

@@ -75,19 +75,19 @@ describe('themeContrast', () => {
expect(ThemeHelper.themeContrast('var(--test)')({ theme: lightTheme })).toEqual('var(--test)');
expect(ThemeHelper.themeContrast('rgb(0,0,0)')({ theme: lightTheme })).toEqual('rgb(0,0,0)');
expect(ThemeHelper.themeContrast('rgba(0,0,0,1)')({ theme: lightTheme })).toEqual(
'rgba(0,0,0,1)'
'rgba(0,0,0,1)',
);
expect(
ThemeHelper.themeContrast(ThemeHelper.themeColor('backgroundPrimary')({ theme: lightTheme }))(
{
theme: lightTheme,
}
)
},
),
).toEqual('rgb(252,252,253)');
expect(
ThemeHelper.themeContrast(ThemeHelper.themeAvatarColor('luke')({ theme: lightTheme }))({
theme: lightTheme,
})
}),
).toEqual('rgb(209,215,254)');
expect(
ThemeHelper.themeContrast('backgroundPrimary')({
@@ -95,7 +95,7 @@ describe('themeContrast', () => {
...lightTheme,
contrasts: { ...lightTheme.contrasts, backgroundPrimary: 'inherit' },
},
})
}),
).toEqual('inherit');
});
});
@@ -106,17 +106,17 @@ describe('themeBorder', () => {
});
it('should allow to override the color of the border', () => {
expect(ThemeHelper.themeBorder('focus', 'primaryLight')({ theme: lightTheme })).toEqual(
'4px solid rgba(123,135,217,0.2)'
'4px solid rgba(123,135,217,0.2)',
);
});
it('should allow to override the opacity of the border', () => {
expect(ThemeHelper.themeBorder('focus', undefined, 0.5)({ theme: lightTheme })).toEqual(
'4px solid rgba(197,205,223,0.5)'
'4px solid rgba(197,205,223,0.5)',
);
});
it('should allow to pass a CSS prop as color name', () => {
expect(
ThemeHelper.themeBorder('focus', 'var(--outlineColor)', 0.5)({ theme: lightTheme })
ThemeHelper.themeBorder('focus', 'var(--outlineColor)', 0.5)({ theme: lightTheme }),
).toEqual('4px solid var(--outlineColor)');
});
});
@@ -124,25 +124,25 @@ describe('themeBorder', () => {
describe('themeShadow', () => {
it('should work for light theme', () => {
expect(ThemeHelper.themeShadow('xs')({ theme: lightTheme })).toEqual(
'0px 1px 2px 0px rgba(29,33,47,0.05)'
'0px 1px 2px 0px rgba(29,33,47,0.05)',
);
});
it('should allow to override the color of the shadow', () => {
expect(ThemeHelper.themeShadow('xs', 'backgroundPrimary')({ theme: lightTheme })).toEqual(
'0px 1px 2px 0px rgba(252,252,253,0.05)'
'0px 1px 2px 0px rgba(252,252,253,0.05)',
);
expect(ThemeHelper.themeShadow('xs', 'transparent')({ theme: lightTheme })).toEqual(
'0px 1px 2px 0px transparent'
'0px 1px 2px 0px transparent',
);
});
it('should allow to override the opacity of the shadow', () => {
expect(ThemeHelper.themeShadow('xs', 'backgroundPrimary', 0.8)({ theme: lightTheme })).toEqual(
'0px 1px 2px 0px rgba(252,252,253,0.8)'
'0px 1px 2px 0px rgba(252,252,253,0.8)',
);
});
it('should allow to pass a CSS prop as color name', () => {
expect(ThemeHelper.themeShadow('xs', 'var(--shadowColor)')({ theme: lightTheme })).toEqual(
'0px 1px 2px 0px var(--shadowColor)'
'0px 1px 2px 0px var(--shadowColor)',
);
});
});

+ 1
- 1
server/sonar-web/design-system/src/helpers/keyboard.ts Ver arquivo

@@ -55,7 +55,7 @@ export function isInput(event: KeyboardEvent): boolean {
}

export function isTextarea(
event: KeyboardEvent
event: KeyboardEvent,
): event is KeyboardEvent & { target: HTMLTextAreaElement } {
return event.target instanceof HTMLTextAreaElement;
}

+ 7
- 7
server/sonar-web/design-system/src/helpers/positioning.ts Ver arquivo

@@ -80,7 +80,7 @@ const MARGIN_TO_EDGE = 4;
export function popupPositioning(
toggleNode: Element,
popupNode: Element,
placement: PopupPlacement = PopupPlacement.Bottom
placement: PopupPlacement = PopupPlacement.Bottom,
) {
const toggleRect = toggleNode.getBoundingClientRect();
const popupRect = popupNode.getBoundingClientRect();
@@ -136,12 +136,12 @@ export function popupPositioning(

const inBoundariesLeft = Math.min(
Math.max(left, getMinLeftPlacement(toggleRect)),
getMaxLeftPlacement(toggleRect, popupRect)
getMaxLeftPlacement(toggleRect, popupRect),
);

const inBoundariesTop = Math.min(
Math.max(top, getMinTopPlacement(toggleRect)),
getMaxTopPlacement(toggleRect, popupRect)
getMaxTopPlacement(toggleRect, popupRect),
);

return {
@@ -157,27 +157,27 @@ export function popupPositioning(
function getMinLeftPlacement(toggleRect: DOMRect) {
return Math.min(
MARGIN_TO_EDGE, // Left edge of the sceen
toggleRect.left + toggleRect.width / 2 // Left edge of the screen when scrolled
toggleRect.left + toggleRect.width / 2, // Left edge of the screen when scrolled
);
}

function getMaxLeftPlacement(toggleRect: DOMRect, popupRect: DOMRect) {
return Math.max(
document.documentElement.clientWidth - popupRect.width - MARGIN_TO_EDGE, // Right edge of the screen
toggleRect.left + toggleRect.width / 2 - popupRect.width // Right edge of the screen when scrolled
toggleRect.left + toggleRect.width / 2 - popupRect.width, // Right edge of the screen when scrolled
);
}

function getMinTopPlacement(toggleRect: DOMRect) {
return Math.min(
MARGIN_TO_EDGE, // Top edge of the sceen
toggleRect.top + toggleRect.height / 2 // Top edge of the screen when scrolled
toggleRect.top + toggleRect.height / 2, // Top edge of the screen when scrolled
);
}

function getMaxTopPlacement(toggleRect: DOMRect, popupRect: DOMRect) {
return Math.max(
document.documentElement.clientHeight - popupRect.height - MARGIN_TO_EDGE, // Bottom edge of the screen
toggleRect.top + toggleRect.height / 2 - popupRect.height // Bottom edge of the screen when scrolled
toggleRect.top + toggleRect.height / 2 - popupRect.height, // Bottom edge of the screen when scrolled
);
}

+ 3
- 3
server/sonar-web/design-system/src/helpers/theme.ts Ver arquivo

@@ -39,7 +39,7 @@ export function themeContrast(name: ThemeColors | CSSColor) {
export function themeBorder(
name: keyof Theme['borders'] = 'default',
color?: ThemeColors | CSSColor,
opacity?: number
opacity?: number,
) {
return function ({ theme }: ThemedProps) {
const [width, style, ...rgba] = theme.borders[name];
@@ -50,7 +50,7 @@ export function themeBorder(
export function themeShadow(
name: keyof Theme['shadows'],
color?: ThemeColors | CSSColor,
opacity?: number
opacity?: number,
) {
return function ({ theme }: ThemedProps) {
const shadows = theme.shadows[name];
@@ -89,7 +89,7 @@ function getColor(
theme: Theme,
[r, g, b, a]: number[],
colorOverride?: ThemeColors | CSSColor,
opacityOverride?: number
opacityOverride?: number,
) {
// Custom CSS property or rgb(a) color, return it directly
if (

+ 10
- 0
server/sonar-web/yarn.lock Ver arquivo

@@ -6940,6 +6940,7 @@ __metadata:
postcss: 8.4.31
postcss-calc: 9.0.1
postcss-custom-properties: 12.1.11
prettier: ^3.1.0
react-toastify: 8.2.0
twin.macro: 3.4.0
typescript: 5.2.2
@@ -11538,6 +11539,15 @@ __metadata:
languageName: node
linkType: hard

"prettier@npm:^3.1.0":
version: 3.1.0
resolution: "prettier@npm:3.1.0"
bin:
prettier: bin/prettier.cjs
checksum: 44b556bd56f74d7410974fbb2418bb4e53a894d3e7b42f6f87779f69f27a6c272fa7fc27cec0118cd11730ef3246478052e002cbd87e9a253f9cd04a56aa7d9b
languageName: node
linkType: hard

"pretty-format@npm:^27.0.0, pretty-format@npm:^27.4.6":
version: 27.4.6
resolution: "pretty-format@npm:27.4.6"

Carregando…
Cancelar
Salvar