"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",
"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",
"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",
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`}
overlay={modifiedChildren[index].props.children as React.ReactNode}
>
{modifiedChildren[index]}
- </Tooltip>
+ </Tooltip>,
);
} else if (
isLastBreadcrumb ||
k,
});
},
- [padding]
+ [padding],
);
const boundNode = React.useCallback(
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>) => {
const dMaxX = maxX > x2 ? maxX - x2 : 0;
return [dMinX, availableWidth - dMaxX];
},
- [items]
+ [items],
);
const getYRange = React.useCallback(
const dMaxY = maxY > y1 ? maxY - y1 : 0;
return [availableHeight - dMaxY, dMinY];
},
- [items]
+ [items],
);
const getTicks = React.useCallback(
: TICKS_COUNT * zoomAmount;
return scale.ticks(ticksCount);
},
- [transform]
+ [transform],
);
const renderXGrid = React.useCallback(
return <g>{lines}</g>;
},
- [transform, displayXGrid]
+ [transform, displayXGrid],
);
const renderYGrid = React.useCallback(
return <g>{lines}</g>;
},
- [displayYGrid, transform]
+ [displayYGrid, transform],
);
const renderXTicks = React.useCallback(
return <g>{ticks}</g>;
},
- [displayXTicks, formatXTick, transform]
+ [displayXTicks, formatXTick, transform],
);
const renderYTicks = React.useCallback(
return <g>{ticks}</g>;
},
- [displayYTicks, formatYTick, transform]
+ [displayYTicks, formatYTick, transform],
);
const renderChart = (width: number) => {
event.preventDefault();
onClick?.(data);
},
- [data, onClick]
+ [data, onClick],
);
const circle = (
'code-snippet-simple-oneline': isSimpleOneLine,
},
className,
- 'fs-mask'
+ 'fs-mask',
)}
>
{!noCopy && copyButton}
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`}
--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,
--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;
+ `;
function InternalLocationMarker(
{ className, onClick, text, selected }: Props,
- ref: LegacyRef<HTMLDivElement>
+ ref: LegacyRef<HTMLDivElement>,
) {
return (
<StyledMarker
classNames(
'sw-flex sw-items-center',
{ active: isDefined(active) ? active : isActive },
- className
+ className,
)
}
{...linkProps}
onClick(event);
}
},
- [onClick, blurAfterClick, preventDefault, stopPropagation, disabled]
+ [onClick, blurAfterClick, preventDefault, stopPropagation, disabled],
);
return (
disabled,
selected,
},
- className
+ className,
)}
onClick={isActionable && !disabled && !selected ? onClick : undefined}
role={isActionable ? 'radio' : 'presentation'}
// position (which is no longer correct).
this.positionTooltip();
}
- }
+ },
);
}
}
adjustArrowPosition = (
placement: PopupPlacement,
- { leftFix, topFix, height, width }: Measurements
+ { leftFix, topFix, height, width }: Measurements,
) => {
switch (placement) {
case PopupPlacement.Left:
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,
};
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();
}
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();
expect(
screen.getByRole('button', {
name: 'dismiss',
- })
+ }),
).toBeVisible();
await user.click(
screen.getByRole('button', {
name: 'dismiss',
- })
+ }),
);
expect(onDismiss).toHaveBeenCalledTimes(1);
return renderWithContext(
<Banner {...props} variant="warning">
<Note className="sw-body-sm">{props.children ?? 'Test Message'}</Note>
- </Banner>
+ </Banner>,
);
}
onBarClick={jest.fn()}
width={200}
{...overrides}
- />
+ />,
);
}
<HoverLink to="/first">first</HoverLink>
<HoverLink to="/second">second</HoverLink>
<HoverLink to="/third">third</HoverLink>
- </BreadcrumbsFullWidth>
+ </BreadcrumbsFullWidth>,
);
expect(screen.getAllByRole('link').length).toBe(3);
]}
padding={[0, 0, 0, 0]}
{...props}
- />
+ />,
);
}
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');
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');
return renderWithContext(
<HelmetProvider>
<CodeSnippet snippet={'foo\nbar'} {...props} />
- </HelmetProvider>
+ </HelmetProvider>,
);
}
<p>There's no code here.</p>
`}
- />
+ />,
);
// eslint-disable-next-line testing-library/no-node-access
<p>There's some <code>"code"</code> here.</p>
`}
language="typescript"
- />
+ />,
);
// eslint-disable-next-line testing-library/no-node-access
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);
<ItemButton onClick={jest.fn()}>button</ItemButton>
</Tooltip>,
{},
- { delay: null }
+ { delay: null },
);
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
<ItemRadioButton checked={false} onCheck={noop} value="radios">
Radio item
</ItemRadioButton>
- </DropdownMenu>
+ </DropdownMenu>,
);
}
(variant: DuplicationLabel) => {
setupWithProps({ rating: variant });
expect(screen.getByRole('img', { hidden: true })).toMatchSnapshot();
- }
+ },
);
function setupWithProps(props: Partial<FCProps<typeof DuplicationsIndicator>> = {}) {
function renderExecutionFlowAccordion(
props: Partial<FCProps<typeof ExecutionFlowAccordion>> = {},
- children?: React.ReactNode
+ children?: React.ReactNode,
) {
return render(
<ExecutionFlowAccordion header="header" id="id" {...props}>
{children}
- </ExecutionFlowAccordion>
+ </ExecutionFlowAccordion>,
);
}
return renderWithContext(
<FacetBox name="Test FacetBox" {...props}>
{children}
- </FacetBox>
+ </FacetBox>,
);
}
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} />,
);
}
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} />,
);
}
(rating) => {
renderHotspotRating(rating, 'label');
expect(screen.getByLabelText('label')).toMatchSnapshot();
- }
+ },
);
function renderHotspotRating(rating?: HotspotRatingEnum, label?: string) {
it('should render correctly when uncovered', () => {
expect(
- setupWithProps({ lineNumber: 16, coverageStatus: 'uncovered' }).container
+ setupWithProps({ lineNumber: 16, coverageStatus: 'uncovered' }).container,
).toMatchSnapshot();
});
setupWithProps({
lineNumber: 16,
coverageStatus: 'partially-covered',
- }).container
+ }).container,
).toMatchSnapshot();
});
setupWithProps({
lineNumber: 16,
coverageStatus: 'partially-covered',
- }).container
+ }).container,
).toMatchSnapshot();
});
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} />,
);
}
lineNumber={16}
popup={<div>Popup</div>}
{...props}
- />
+ />,
);
}
});
expect(
setupWithProps({ displayCoverage: false, displaySCM: false, duplicationsCount: 0 }).container
- .firstChild
+ .firstChild,
).toHaveStyle({ '--columns': '44px 26px 1fr' });
});
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} />,
);
}
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>,
);
}
render(
<MainMenuItem>
<a>Hi</a>
- </MainMenuItem>
+ </MainMenuItem>,
);
expect(screen.getByText('Hi')).toHaveStyle({
render(
<MainMenuItem>
<a className="active">Hi</a>
- </MainMenuItem>
+ </MainMenuItem>,
);
expect(screen.getByText('Hi')).toHaveStyle({
render(
<MainMenuItem>
<a className="hover">Hi</a>
- </MainMenuItem>
+ </MainMenuItem>,
);
expect(screen.getByText('Hi')).toHaveStyle({
return renderWithRouter(
<NavBarTabs>
<NavBarTabLink text="test" to="/summary/new_code" />
- </NavBarTabs>
+ </NavBarTabs>,
);
}
});
const { user } = setupWithMemoryRouter(
<button onClick={buttonOnClick} type="button">
<NavLink stopPropagation to="/second" />
- </button>
+ </button>,
);
await user.click(screen.getByRole('link'));
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'));
/>
<Route element={<ShowPath />} path="/second" />
</Routes>
- </MemoryRouter>
+ </MemoryRouter>,
);
};
setupWithProps({ status, size });
expect(screen.getByRole('status')).toHaveAttribute('width', SIZE_VS_WIDTH[size]);
- }
+ },
);
it('should display tooltip', () => {
title="Selection Card"
titleInfo="info"
{...props}
- />
+ />,
);
}
// 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',
);
});
expect(screen.getAllByRole('tab')).toHaveLength(3);
expect(screen.getByRole('tab', { name: 'second' })).toHaveAttribute(
'aria-controls',
- getTabPanelId(2)
+ getTabPanelId(2),
);
});
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'));
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>,
);
}
});
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>,
);
}
});
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} />,
);
}
return render(
<TutorialStepList>
<TutorialStep title="This is title">These are children</TutorialStep>
- </TutorialStepList>
+ </TutorialStepList>,
);
}
setupWithProps({ hash: '7daf6c79d4802916d83f6266e24850af' });
expect(screen.getByRole('img')).toHaveAttribute(
'src',
- 'http://example.com/7daf6c79d4802916d83f6266e24850af.jpg?s=48'
+ 'http://example.com/7daf6c79d4802916d83f6266e24850af.jpg?s=48',
);
});
function setupWithProps(props: Partial<FCProps<typeof Avatar>> = {}) {
return render(
- <Avatar enableGravatar gravatarServerUrl={gravatarServerUrl} name="foo" {...props} />
+ <Avatar enableGravatar gravatarServerUrl={gravatarServerUrl} name="foo" {...props} />,
);
}
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`}
function LineFindingFunc(
{ message, issueKey, selected = true, className, onIssueSelect }: Props,
- ref: Ref<HTMLButtonElement>
+ ref: Ref<HTMLButtonElement>,
) {
return (
<LineFindingStyled
if (pointerRef.current && issueFindingRef?.current) {
setDistance(
issueFindingRef.current.getBoundingClientRect().top -
- pointerRef.current.getBoundingClientRect().bottom
+ pointerRef.current.getBoundingClientRect().bottom,
);
}
}, [pointerRef, issueFindingRef]);
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);
render(
<CustomIcon>
<path d="test" />
- </CustomIcon>
+ </CustomIcon>,
);
expect(screen.queryByRole('img')).not.toBeInTheDocument();
render(
<CustomIcon aria-label="test">
<path d="test" />
- </CustomIcon>
+ </CustomIcon>,
);
expect(screen.getByRole('img')).toBeVisible();
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,
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`,
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 },
setValue={jest.fn()}
value="foo"
{...props}
- />
+ />,
);
}
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>,
);
}
searchInputAriaLabel=""
value="foo"
{...props}
- />
+ />,
);
}
searchInputAriaLabel="search"
selectedElements={[]}
{...props}
- />
+ />,
);
}
return render(
<RadioButton checked={false} onCheck={jest.fn()} value="value" {...props}>
foo
- </RadioButton>
+ </RadioButton>,
);
}
searchInputAriaLabel=""
value="foo"
{...props}
- />
+ />,
);
}
const loadOptions = (
query: string,
- cb: (options: Array<LabelValueSelectOption<string>>) => void
+ cb: (options: Array<LabelValueSelectOption<string>>) => void,
) => {
cb(defaultOptions.filter((o) => o.label.includes(query)));
};
loadOptions={loadOptions}
placeholder="search for things"
{...props}
- />
+ />,
);
}
<NumberedList>
<NumberedListItem>First item</NumberedListItem>
<NumberedListItem>Second item</NumberedListItem>
- </NumberedList>
+ </NumberedList>,
);
expect(screen.getAllByRole('listitem')).toHaveLength(2);
});
<UnorderedList>
<ListItem>First item</ListItem>
<ListItem>Second item</ListItem>
- </UnorderedList>
+ </UnorderedList>,
);
expect(screen.getAllByRole('listitem')).toHaveLength(2);
});
onClose={jest.fn()}
secondaryButtonLabel="Close"
{...props}
- />
+ />,
);
}
return renderWithContext(
<Modal onClose={jest.fn()} {...props}>
{children}
- </Modal>
+ </Modal>,
);
}
<Modal onClose={jest.fn()} {...props}>
<div>Hello there!</div>
<div>How are you?</div>
- </Modal>
+ </Modal>,
);
}
return render(
<SubnavigationAccordion header="Header" id="test" {...props}>
<span>Foo</span>
- </SubnavigationAccordion>
+ </SubnavigationAccordion>,
);
}
return render(
<SubnavigationItem active={false} onClick={jest.fn()} value="foo" {...props}>
<button type="button">Foo</button>
- </SubnavigationItem>
+ </SubnavigationItem>,
);
}
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)',
);
});
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)');
});
});
describe('themeContrast', () => {
it('should work for light theme', () => {
expect(ThemeHelper.themeContrast('backgroundPrimary')({ theme: lightTheme })).toEqual(
- 'rgb(8,9,12)'
+ 'rgb(8,9,12)',
);
});
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')({
...lightTheme,
contrasts: { ...lightTheme.contrasts, backgroundPrimary: 'inherit' },
},
- })
+ }),
).toEqual('inherit');
});
});
});
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)');
});
});
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)',
);
});
});
}
export function isTextarea(
- event: KeyboardEvent
+ event: KeyboardEvent,
): event is KeyboardEvent & { target: HTMLTextAreaElement } {
return event.target instanceof HTMLTextAreaElement;
}
export function popupPositioning(
toggleNode: Element,
popupNode: Element,
- placement: PopupPlacement = PopupPlacement.Bottom
+ placement: PopupPlacement = PopupPlacement.Bottom,
) {
const toggleRect = toggleNode.getBoundingClientRect();
const popupRect = popupNode.getBoundingClientRect();
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 {
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
);
}
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];
export function themeShadow(
name: keyof Theme['shadows'],
color?: ThemeColors | CSSColor,
- opacity?: number
+ opacity?: number,
) {
return function ({ theme }: ThemedProps) {
const shadows = theme.shadows[name];
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 (
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
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"